วัตถุประสงค์ของ 'ที' คืออะไร?


90

ประเพณีทั้งหมดที่teeฉันเคยเห็นเป็นเช่น:

 do_something | tee -a logfile

หรือ:

do_something_else | tee logfile

มีการteeคิดค้นสำหรับผู้ที่ไม่ทราบว่าคุณสามารถทำเช่นเดียวกันกับการเปลี่ยนเส้นทางท่อเปลือก? เช่น:

do_something >> logfile

หรือ:

do_something_else > logfile

มันเหมือนกันจริงและใช้แป้นพิมพ์น้อยกว่าในการพิมพ์ ฉันไม่เห็นคุณลักษณะที่ซ่อนอยู่อะไรteeบ้าง


62
วิธีนี้ได้รับการตอบไม่ได้โดยบรรทัดแรกของหน้าคน"... และเขียนออกมาตรฐานและไฟล์" ? คำตอบนั้นน่าสนใจ แต่พูดอย่างกว้าง ๆ ว่าท่อมีประโยชน์เพียงใดช่วยตอกย้ำว่าคำถามนี้ดูกว้างเกินไปและอาจถูกปิด
Xen2050

3
@ Xen2050 คำถามไม่สามารถถูกตำหนิได้สำหรับคำตอบที่กว้างเกินไป คำถามคือที่เฉพาะเจาะจงมากตามที่เป็นอยู่ในปัจจุบันคำตอบการจัดอันดับสูงสุด
Jon Bentley

1
@ JonBentley คำถามไม่เหมือน"ปัญหาเฉพาะที่มีรายละเอียดเพียงพอที่จะระบุคำตอบที่เพียงพอ" (เป็นกล่องโต้ตอบปิดอ่าน) ดูเหมือนว่า: "หากคำถามของคุณสามารถตอบได้ทั้งเล่มหรือมีคำตอบที่ถูกต้องมากมาย (แต่ไม่สามารถระบุได้ว่าถ้ามี - ถูกต้อง) ซึ่งอาจกว้างเกินไปสำหรับรูปแบบของเรา" (ที่มา: ศูนย์ช่วยเหลือ )
Xen2050

4
@ Xen2050 เราอ่านคำถามเดียวกันหรือไม่? ดูเหมือนจะเฉพาะเจาะจงมากสำหรับฉัน - อะไรคือความแตกต่างระหว่างทีกับท่อ ได้รับคำตอบอย่างเพียงพอโดยใช้สองประโยค ห่างไกลจากหนังสือทั้งเล่ม ความจริงที่ว่าบางคำตอบเลือกที่จะออกไปสัมผัสแทนเจนต์ไม่มีอะไรเกี่ยวข้องกับขอบเขตของคำถาม
Jon Bentley

@JonBentley: พวกเรากำลังอ่านคำถามเดียวกันอยู่เหรอ? R Moog ชนิดของการจัดเรียงของหมายถึงเป็นคำถามที่ค่อนข้างเน้นดี - สิ่งที่เป็นความแตกต่างระหว่างtee และI / O เปลี่ยนเส้นทาง ?   ความจริงที่ว่า "การเปลี่ยนเส้นทางไปป์ของเชลล์เช่นและ" ไม่ใช่จุดที่ชอบและเป็นอาร์กิวเมนต์สำหรับการปิดที่ไม่ชัดเจน แต่จริงๆแล้วมันถามคำถามหลายข้อ:“ อะไรคือจุดประสงค์ของมัน”,“ ถูกคิดค้นขึ้นสำหรับผู้ที่ไม่ทราบว่าคุณสามารถทำเช่นเดียวกันกับการเปลี่ยนเส้นทางของ shell pipe?” และ“ ฉันไม่เห็นคุณสมบัติที่ซ่อนอยู่อะไร?” อย่างน้อยสองคำถามนั้นกว้างเกินไป >>>teeteetee
G-Man

คำตอบ:


242

สิ่งที่คุณไม่เห็นคือการที่do_something | tee -a logfileทำให้การส่งออกลงlogfile และที่ stdout ในขณะที่do_something >> logfileทำให้มันเพียงเข้าสู่ logfile

วัตถุประสงค์ของteeการสร้างอินพุตหนึ่งภาพจำลองเอาต์พุตหลายรายการ - เหมือนกับในการข้าม 'T'

แก้ไข

มีความคิดเห็นเกี่ยวกับวิธีการที่teeช่วยให้ใช้งานsudoได้สะดวกยิ่งขึ้น นี่คือข้างจุด: cat, ddหรืออาจจะดีกว่าbufferให้เป็นไปได้นี้มีประสิทธิภาพการทำงานที่ดีกว่าถ้าคุณไม่จำเป็นต้องใช้ผลหลาย ใช้teeสำหรับสิ่งที่ออกแบบมาไม่ใช่เพื่อสิ่งที่ "สามารถทำได้"


37
เอาต์พุตหลายรายการเป็นกุญแจสำคัญ teeสามารถใช้อาร์กิวเมนต์หลายตัวและเขียนไปยังไฟล์หลายไฟล์พร้อมกัน
Kamil Maciorowski

20
ฉันจะเรียกมันว่าข้อต่อท่อทีไม่ใช่ทางแยก (เหมือนอยู่ในสี่แยกถนน?) สิ่งของมาทางเดียวและออกไปทั้งสองทาง
user20574

7
ฉันจะใช้catอย่างตรงไปตรงมาแทนที่จะเป็นteeเช่นecho /var/work/core.%p | sudo tee /proc/sys/kernel/core_patternอะไร? echo /var/work/core.%p | sudo cat > /proc/sys/kernel/core_patternไม่ทำงานเนื่องจากการเปลี่ยนเส้นทางถูกประมวลผลโดยเชลล์ที่ไม่ใช่ sudo สำหรับdd, echo /var/work/core.%p | sudo dd of=/proc/sys/kernel/core_patternทำงาน แต่มักจะเป็นเครื่องมือที่มีความสามารถในการสู้ทำให้เกิดความเสียหายโดยเฉพาะอย่างยิ่งภายใต้dd sudoสำหรับbuffer, มันไม่ได้ติดตั้งโดยปริยายใน RedHat- หรือ Ubuntu ที่ใช้ distros ใด ๆ ที่ฉันต้องส่ง (หรือ MacOS) ...
Digital Trauma

3
@EugenRieck ฉันได้รับจุดของคุณเกี่ยวกับความสัมพันธ์ 1: n ระหว่างใน: ออกเป็นหน้าที่หลัก อย่างไรก็ตามทั้งตัวในcatและไม่/bin/catทำงานสำหรับฉันในสถานการณ์นี้ ไม่สำคัญว่าcatมาจากไหน- >จะยังคงจัดการโดยเชลล์ระดับบนสุด (ไม่ใช่ sudo) ข้อดีของการใช้teeเกินcatในสถานการณ์นี้คืออนุญาตให้ส่งออกไฟล์เป็นพารามิเตอร์บรรทัดคำสั่ง (ไม่ใช่การเปลี่ยนเส้นทาง) ddแน่นอนว่าเป็นตัวเลือกที่ทำงานได้แม้ว่าฉันจะยังคงชอบteeสิ่งนี้อยู่
Digital Trauma

3
@EugenRieck เชลล์ชนิดใดที่มีcatและอยู่teeในตัว? และเวอร์ชันใดที่sudoสามารถรันเชลล์บิวด์อินได้?
wjandrea

118

Tee ไม่ไร้ประโยชน์

คุณอาจรู้หรือไม่? ถ้าไม่อ่าน! หรือถ้าคุณรู้ว่ามันทำงานอย่างไร แต่ไม่แน่ใจว่าทำไมมันถึงมีอยู่ให้ข้ามไปจนสุดเพื่อดูว่ามันเข้ากับปรัชญาของ Unix ได้อย่างไร

อะไรคือวัตถุประสงค์ของการtee?

ที่ง่ายที่สุดจะใช้ข้อมูลในอินพุตมาตรฐานและเขียนลงในเอาต์พุตมาตรฐานและหนึ่งไฟล์ (หรือมากกว่า) มันได้รับการเปรียบกับชิ้นส่วนประปาในวิธีที่มันแยกหนึ่งอินพุตเป็นสองเอาท์พุท (และสองทิศทาง)

ตัวอย่าง

ลองมาตัวอย่างแรกของคุณ:

do_something | tee -a logfile

สิ่งนี้จะเอาท์พุทของdo_somethingและผนวกเข้ากับ logfile ในขณะที่ยังแสดงให้ผู้ใช้ ในความเป็นจริงหน้า Wikipedia ที่teeมีต่อไปนี้เป็นตัวอย่างที่สอง:

ในการดูและผนวกเอาต์พุตจากคำสั่งไปยังไฟล์ที่มีอยู่:

  lint program.c | tee -a program.lint

สิ่งนี้แสดงเอาต์พุตมาตรฐานของคำสั่ง lint program.c ที่คอมพิวเตอร์และในขณะเดียวกันก็จะเพิ่มสำเนาของมันไว้ที่ส่วนท้ายของไฟล์ program.lint หากไฟล์ program.lint ไม่มีอยู่ไฟล์นั้นจะถูกสร้างขึ้น

ตัวอย่างถัดไปมีประโยชน์หลายอย่าง: การเพิ่มระดับสิทธิ์ :

วิธีอนุญาตให้มีการเพิ่มระดับสิทธิ์:

cat ~/.ssh/id_rsa.pub | ssh admin@server "sudo tee -a /root/.ssh/authorized_keys2 > /dev/null"

ตัวอย่างนี้แสดงการทีใช้เพื่อข้ามข้อ จำกัด โดยธรรมชาติในsudoคำสั่ง sudoไม่สามารถไพพ์เอาต์พุตมาตรฐานไปยังไฟล์ โดยการทิ้งการสตรีมมาตรฐานลงใน/dev/nullเรายังระงับเอาต์พุตที่มิร์เรอร์ในคอนโซล คำสั่งด้านบนให้การเข้าถึงรูทผู้ใช้ปัจจุบันไปยังเซิร์ฟเวอร์ผ่าน ssh โดยการติดตั้งกุญแจสาธารณะของผู้ใช้ไปยังรายการการอนุญาตคีย์ของเซิร์ฟเวอร์

หรือบางทีคุณต้องการที่จะเอาท์พุทของคำสั่งหนึ่งเขียนมันที่ไหนสักแห่งและใช้มันเป็นอินพุตไปยังคำสั่งอื่น?

คุณยังสามารถใช้คำสั่ง tee เพื่อเก็บเอาต์พุตของคำสั่งไปยังไฟล์และเปลี่ยนทิศทางเอาต์พุตเดียวกันกับอินพุตไปยังคำสั่งอื่น

คำสั่งต่อไปนี้จะสำรองข้อมูลของรายการ crontab และส่งรายการ crontab เป็นอินพุตไปยังคำสั่ง sed ซึ่งจะทำการทดแทน หลังจากการทดแทนมันจะถูกเพิ่มเป็นงาน cron ใหม่

$ crontab -l | tee crontab-backup.txt | sed 's/old/new/' | crontab –

(เครดิตกับตัวอย่างการใช้คำสั่ง Tee )

Tee ทำงานร่วมกับปรัชญา Unix:

เขียนโปรแกรมที่ทำสิ่งหนึ่งและทำได้ดี เขียนโปรแกรมเพื่อทำงานร่วมกัน เขียนโปรแกรมเพื่อจัดการสตรีมข้อความเนื่องจากเป็นอินเตอร์เฟสสากล

(เครดิตกับพื้นฐานของปรัชญา Unix )

tee เหมาะกับสิ่งเหล่านี้:

  • มันทำสิ่งหนึ่ง: สร้างสำเนาของอินพุตเพิ่มเติม
  • ใช้งานได้กับโปรแกรมอื่น ๆ เพราะเป็นกาว (หรือชิ้นส่วนประปา 'T' หากคุณต้องการ) ที่ช่วยให้โปรแกรมอื่นทำงานร่วมกันได้ดังตัวอย่างด้านบน
  • มันทำได้โดยการจัดการสตรีมข้อความที่กำหนดในอินพุตมาตรฐาน

3
@ โจ: sudo tee -aอาจจะเป็นนวัตกรรมที่ใหม่กว่า (ฉันเห็นครั้งแรกในคู่มือ Ubuntu / wikis โดยเฉพาะอย่างยิ่งสำหรับการตั้งค่าสิ่งต่าง ๆ/proc/sysเพราะการเปลี่ยนไปใช้ Ubuntu เป็นเมื่อฉันเปลี่ยนไปsudoใช้ระบบพื้นฐาน (วิธีการกำหนดค่า Ubuntu ตามค่าเริ่มต้น) แทนที่จะใช้suกับ รหัสผ่านรูท) ฉันคิดว่าteeมาก่อนsudoดังนั้นมันจึงไม่มีเหตุผลสำหรับการteeมีอยู่ คุณไม่จำเป็นต้องสำหรับการที่มันเป็นเพียงแค่สั้นพิมพ์โต้ตอบกว่าtee sudo sh -c 'cat > output'
Peter Cordes

1
ด้วยเปลือกหอยที่ทันสมัยเช่นทุบตีคุณสามารถที่จะเลี้ยงสองท่อเช่นtee foo | tee >(pipe2) | pipe1หรือสิ่งที่สนุกอีกอย่างหนึ่งคือffmpeg ... |& tee /dev/tty | sed 's/.*\r// > encode.logการเห็นการอัพเดตสถานะแบบโต้ตอบบน tty ในขณะที่ลบ "บรรทัด" ที่ลงท้ายด้วย carriage-return แทนที่จะขึ้นบรรทัดใหม่สำหรับการบันทึกที่แท้จริง (เช่นกรองการอัพเดทสถานะบรรทัด) โดยทั่วไปคุณสามารถติดtee /dev/ttyที่ใดก็ได้ในไปป์ไลน์เป็น debug-print
Peter Cordes

2
มันมีข้อ จำกัด น้อยกว่า sudo ที่คุณกำลังแก้ไขและการ จำกัด การตีความของ shell> เมื่อคุณรันคำสั่งด้วย sudo stdout จะได้รับการส่งกลับไปยังโปรแกรมเชลล์ของคุณและการเปลี่ยนเส้นทางด้วย> จะทำงานโดยได้รับอนุญาตจากเชลล์ หากคุณต้องการเขียนด้วยสิทธิ์ระดับสูงคุณต้องมีส่วนที่ยกระดับของไปป์ไลน์เป็นสิ่งที่เขียน มีหลายวิธีที่จะทำเช่นนี้ขึ้นอยู่กับผลกระทบที่คุณจะทำ หากคุณต้องการใช้> บางอย่างเช่น 'sudo bash -c "command> outfile"' จะทำงาน
Perkins

@Perkins เปลือกแยกวิเคราะห์>และตั้งค่าการเปลี่ยนเส้นทางก่อน sudo แม้จะได้รับexec'd ดังนั้นจึงเป็นที่แน่นอนไม่ได้ข้อ จำกัด ของ sudo ว่ามันไม่ได้จัดการกับสิ่งที่มันไม่เคยเห็น :) ฉันมักจะพยายามอ้างถึงสิ่งนี้ว่า "เวิร์กโฟลว์ sudo" หรือคำที่คล้ายกันเมื่อฉันอธิบายมันแทนที่จะอธิบาย sudo เอง
dannysauer

sudo tee -aIMHO เป็นการล่วงละเมิดของที ใช้sudo cat, sudo ddหรือ (ที่มีประสิทธิภาพที่ดีที่สุดในหลาย ๆ กรณี) sudo bufferถ้าคุณไม่จำเป็นต้องใช้ผลหลาย
Eugen Rieck

70

มันเหมือนกันจริงและใช้แป้นพิมพ์น้อยกว่าในการพิมพ์

มันไม่เหมือนกันเลย ...

สิ่งต่อไปนี้ดูเหมือนจะค่อนข้างเท่ากัน แต่ไม่ใช่:

$ echo "hi" > test.txt
$ echo "hi" | tee test.txt
hi

ความแตกต่างที่สำคัญคือข้อมูลก่อนหน้านี้ได้เขียนข้อมูลไปยังไฟล์ที่ระบุเท่านั้นในขณะที่ข้อมูลหลังได้เขียนhiลงในเทอร์มินัล ( stdout) และไฟล์ที่มีชื่อดังที่แสดงด้านล่าง:

เปลี่ยนเส้นทางเทียบกับที


teeช่วยให้คุณสามารถเขียนข้อมูลไปยังไฟล์และใช้มันในขั้นตอนถัดไปทำให้คุณสามารถทำสิ่งที่มีประโยชน์ - เช่นการเก็บข้อมูลจากทางไปป์ไลน์:

grep '^look ' interesting_file.txt \
  | tee interesting_lines.txt \
  | sort

หรือคุณสามารถเขียนไปยังไฟล์ที่มีสิทธิ์ยกระดับโดยไม่ต้องให้สิทธิ์ยกระดับไปป์ไลน์ทั้งหมด (ที่นี่echoจะเรียกใช้ในฐานะผู้ใช้ขณะที่teeเขียนไปยังไฟล์เป็นroot):

echo 0 \
  | sudo tee /proc/sys/net/ipv4/ip_forward

ด้วยteeคุณสามารถเขียนไปยังหลาย ๆ ไฟล์ ( และ stdout ):

echo "hi" \
  | tee a.txt b.txt

เป็นไปได้ที่จะใช้execกับteeบันทึกผลลัพธ์ทั้งหมดของสคริปต์ไปยังไฟล์ในขณะที่ยังอนุญาตให้ผู้สังเกตการณ์ ( stdout) ดูข้อมูล:

exec > >( tee output.log )

2
ไม่ลืมexec > >(tee "$LOGFILE") 2>&1ในสคริปต์ทุบตีซึ่งจะช่วยให้การส่งออก stdout สคริปต์และ stderr ทั้งจำทั้ง stdout $LOGFILEและไฟล์ที่ชี้ไปตาม
rexkogitans

@rexkogitans 2> & 1 นั่นไม่ใช่ไวยากรณ์ชุดคำสั่ง cmd หรือไม่
dmb

@dmb: เป็นไวยากรณ์ของเชลล์สำหรับ "send stderr (= 2) ไปที่เดียวกับ stdout (= 1)"
psmears

@rexkogitans มันเป็นคำถามที่ยุติธรรมจริง ๆ ฉันไม่รู้จริงๆว่าคุณไม่ได้ใช้ "Windoze" มาสิบปีแล้ว ฉันใช้2>&1เพื่อวางผลลัพธ์และ err ไฟล์ txt ใน windows
dmb

1
@dmb ฉันขอโทษที่ทำตัวหยาบคาย ทุกอย่างเกี่ยวกับความคิดเห็นของ psmears เห็นได้ชัดว่า Windows ใช้ Unix แบบที่นี่
rexkogitans

27

นี่คือที:
ป้อนคำอธิบายรูปภาพที่นี่

ข้อต่อท่อรูปตัว T มันมีทางเข้าและสองแยกต่างหาก
กล่าวอีกนัยหนึ่งมันแยกหนึ่งท่อเป็นสอง เหมือนส้อมบนถนน

ในทำนองเดียวกันไพteeพ์ ( |) ที่อนุญาตให้คุณเปลี่ยนทิศทางอินพุตมาตรฐานของคุณไปยังเอาต์พุตแยกกันสองตัว


ตัวอย่าง
Say ls /เช่นคุณพิมพ์
คุณจะได้ผลลัพธ์ที่ดูเหมือน:

Applications    Network     Users       bin        dev      net      private    tmp         var
Library         System      Volumes     cores      etc      home     opt        sbin        usr

เปลี่ยนทิศทางเอาต์พุตไปยังไฟล์ข้อความls / > ls.txtและไม่แสดงเอาต์พุตในเชลล์เฉพาะในไฟล์ข้อความผลลัพธ์

ต้องการที่จะเห็นผลลัพธ์และส่งผ่านไปยังไฟล์ข้อความในเวลาเดียวกันหรือไม่
เพิ่ม a teeไปยัง pipe ของคุณ ( |) เช่น:ls / | tee ls.txt


เปรียบเทียบทั้งสอง:

ls /          >          ls.txt
ls /        | tee        ls.txt

4
+1 สำหรับรูปภาพที่เรารู้ว่ามีค่าหนึ่งพันคำ
Sergiy Kolodyazhnyy

หากคุณเลือกชิ้นส่วน hosepipe Garden คุณจะสอดคล้องกับคำเปรียบเทียบดั้งเดิมของ Doug McIlroy
JdeBP

@JdeBP ขออภัยฉันไม่รู้ว่าใครเป็นใคร เขาเป็นผู้เขียนต้นฉบับของยูทิลิตี้หรืออะไร? การไหลของข้อมูลและกระแสไฟฟ้าทางกายภาพมักจะถูกเปรียบเทียบกับระบบไฮดรอลิก แต่คุณอาจรู้ว่า อย่างไรก็ตามฉันเพิ่งเลือกสไตล์นี้เพื่อให้ง่ายสุด ๆ จริง ๆ แล้วฉันจะทำเช่นนั้นเพื่อให้คุ้นเคย แต่ความหลากหลายของสวนมีแนวโน้มที่จะมีรูปตัว Y และ / หรือสิ่งที่แนบสายตาที่ซับซ้อนมากขึ้นสำหรับการแนบอุปกรณ์เสริม ฯลฯ มันก็เหมือนกัน
เสียง

1
เอ็มดักลาส McIlroy, ผู้เขียนบันทึกนี้มีชื่อเสียงที่ทำงานที่เบลล์แล็บและชักชวนเคน ธ อมป์สันที่จะใส่ท่อเข้าไปในระบบปฏิบัติการยูนิกซ์
JdeBP

18

ไม่คุณพูดถึงหนึ่งในตัวอย่างที่คุณสามารถเปลี่ยนเส้นทางไปยังไฟล์โดยใช้>และ>>โอเปอเรเตอร์

แต่ทีสามารถทำได้มากกว่านี้ เนื่องจากคุณไปป์มันคุณจึงสามารถไปป์อย่างอื่นได้

ตัวอย่างที่ดีแสดงอยู่ในหน้าวิกิพีเดีย :

find "4DOS" wikipedia.txt | tee 4DOS.txt | sort > 4DOSsorted.txt

โดยทั่วไปคุณสามารถไปป์ที่ Tee ดังนั้นคุณสามารถไปป์จาก Tee ไปยังอย่างอื่นได้ หากสิ่งที่คุณต้องการทำคือเขียนไฟล์บันทึกใช่แล้วคุณไม่จำเป็นต้องใช้ Tee


17

teeอยู่ไกลจากไร้ประโยชน์ ฉันใช้มันตลอดเวลาและดีใจที่มีอยู่ มันเป็นเครื่องมือที่มีประโยชน์มากถ้าคุณมีขั้นตอนที่คุณต้องการแยก ตัวอย่างง่ายๆคือคุณมีไดเรกทอรี$dที่คุณต้องการ tar และคุณต้องการแฮชเพราะคุณเป็นคนหวาดระแวง (อย่างฉัน) และไม่เชื่อใจสื่อเก็บข้อมูลเพื่อเก็บข้อมูลอย่างน่าเชื่อถือ คุณสามารถเขียนมันลงในดิสก์ก่อนแล้วจึงแฮช แต่นั่นจะล้มเหลวหากไฟล์เก็บถาวรได้รับความเสียหายก่อนที่จะถูกแฮช นอกจากนี้คุณต้องอ่านมันและถ้าคุณทำงานกับไฟล์ที่มีขนาดหลายร้อย GB คุณจะรู้ว่าคุณไม่ต้องการที่จะอ่านอีกครั้งถ้ามันไม่จำเป็นต้องเป็น

ดังนั้นสิ่งที่ฉันทำคือเพียงแค่นี้:

tar -c "$d" | tee >(sha256sum) >(cat > "$d"".tar") > /dev/null

มันสร้างลูกทาร์และไปป์เพื่อทีซึ่งจะไปยังเชลล์ย่อยสองอันโดยหนึ่งในนั้นจะถูกแฮชและอีกอันที่มันถูกเขียนไปยังดิสก์

นอกจากนี้ยังเป็นการดีหากคุณต้องการดำเนินการหลายอย่างในไฟล์ขนาดใหญ่:

< file.tar.gz tee >(sha256sum) >(tar -xz) /other/storage/location/file.tar.gz > /dev/null

อ่านไฟล์หนึ่งครั้งแฮชมัน (เพื่อให้คุณสามารถตรวจสอบว่ามันยังคงเป็นตามที่ควร) แยกมันและคัดลอกไปยังตำแหน่งอื่น ไม่จำเป็นต้องอ่านมันสามครั้ง


3
Nitpick: teeไม่สร้าง subshells; เปลือกโทรวิ่งsha5sumและและเชื่อมต่อการส่งออกของพวกเขาที่จะยื่นอธิบายซึ่งจะถูกส่งผ่านไปยังcat teeนอกจากนี้การใช้งานที่ไร้ประโยชน์cat; คุณสามารถใช้การเปลี่ยนเส้นทางอินพุตเพื่อteeอ่านโดยตรงfile.tar.gzได้
chepner

@chepner คุณพูดถูกในคำอุทานครั้งแรก แต่คุณผิดอย่างสมบูรณ์ในเรื่องที่สอง ฉันชอบเขียนไปป์ไลน์ตามลำดับดังนั้นการแสดงว่าอินพุตที่ด้านขวานั้นแย่มากสำหรับการอ่านและการทำเช่นนั้นมีความด้อยกว่าวิธีการของฉันอย่างชัดเจนและไม่ได้เป็นความชอบส่วนตัวของฉันเลย catคือรัก. catคือชีวิต.
UTF-8

6
นอกจากนี้คุณยังสามารถเขียน< file.tar.gz tee >(sha256sum) ...หากคุณมีความกังวลเกี่ยวกับการจัดเรียงคำศัพท์ของการเปลี่ยนเส้นทาง teeแต่นั่นไม่ได้เปลี่ยนความจริงที่ว่ามีความจำเป็นสำหรับกระบวนการแยกเพียงที่จะเลี้ยงไฟล์เดียวไม่มี
chepner

1
@chepner เจ๋งขอบคุณมาก! เรียนรู้บางสิ่งบางอย่างในวันนี้ :)
UTF-8

1
ค่าใช้จ่ายในการเริ่มต้น catค่อนข้างต่ำ ค่าใช้จ่ายของระบบการเขียน + อ่านเพิ่ม 100 GiB แน่นอนลดเวลา CPU และแบนด์วิดท์หน่วยความจำสำหรับตัวอย่างไฟล์ขนาดใหญ่ที่คุณเสนอ จำไว้ว่าแบนด์วิดธ์หน่วยความจำเป็นทรัพยากรที่ใช้ร่วมกันในทุกคอร์ไม่ต้องพูดถึงมลภาวะเพิ่มเติมของแคช L3 จากการคัดลอกนั้น สำหรับ x86 ที่เปิดใช้งานการลดการลดทอนของ Spectre + Meltdown การเรียกใช้ระบบจะมีราคาแพงกว่าที่เคยเป็น คุณกำลังใช้เวลา CPU เพิ่มเติมที่วัดได้ในช่วงเวลาของการคัดลอกนั้น ยัง>(cat > foo)ไม่เข้าใจง่ายกว่าfooIMO
Peter Cordes

12

คำตอบของ Nitpick บน @ bertieb ที่กล่าวว่าตัวอย่างนี้แสดงการใช้ tee เพื่อหลีกเลี่ยงข้อ จำกัด โดยธรรมชาติในคำสั่ง sudo sudo ไม่สามารถไพพ์เอาต์พุตมาตรฐานไปยังไฟล์ได้

ไม่มีข้อ จำกัด โดยธรรมชาติเพียงความเข้าใจผิดของวิธีการประมวลผลคำสั่ง

ตัวอย่าง:

sudo echo 0 > /proc/sys/net/ipv4/ip_forward

เปลือกปัจจุบันแยกวิเคราะห์บรรทัดคำสั่ง ค้นหาการเปลี่ยนเส้นทางผลลัพธ์และดำเนินการนั้น จากนั้นจะดำเนินการคำสั่งซึ่งเป็นsudoและจัดเตรียมบรรทัดคำสั่งที่เหลือเป็นอาร์กิวเมนต์ของคำสั่งที่ดำเนินการ หากเชลล์ปัจจุบันไม่มีสิทธิ์รูทการเปลี่ยนทิศทางเอาต์พุตจะล้มเหลว

echo 0 | sudo tee /proc/sys/net/ipv4/ip_forward

งานนี้เพราะการเปลี่ยนเส้นทางการส่งออกที่มีการรอการตัดบัญชีไปที่teeคำสั่งซึ่งที่จุดที่จะมีสิทธิ์ root sudoเพราะมันกำลังดำเนินการผ่าน

sudo bash -c "echo 0 > /proc/sys/net/ipv4/ip_forward"

ทำงานได้เนื่องจากเชลล์ที่ทำการเปลี่ยนเส้นทางมีสิทธิ์รูต


2
นอกจากนี้คุณอาจจำเป็นต้องsudoสำหรับคำสั่ง แต่ไม่ได้สำหรับการส่งออกไฟล์และเปลี่ยนเส้นทางทำงานได้ดี:sudo foo-needs-privilege > /tmp/this-output-file-doesnt
เดนนิสวิลเลียมสัน

10

ตามที่คนอื่น ๆ ได้กล่าวถึงการไพพ์เอาต์พุตไปยังteeคำสั่งเขียนเอาต์พุตนั้นไปยังทั้งไฟล์และไปยัง stdout

ฉันมักจะใช้teeเมื่อฉันต้องการที่จะจับเอาท์พุทจากคำสั่งที่ใช้เวลานานในการทำงานในขณะที่ยังต้องการที่จะตรวจสอบการมองเห็นเอาท์พุทเป็นคำสั่งทำให้มันใช้ได้ ด้วยวิธีนี้ฉันไม่ต้องรอให้คำสั่งเสร็จสิ้นก่อนที่ฉันจะตรวจสอบผลลัพธ์

สิ่งที่ดูเหมือนจะไม่ได้รับการกล่าวถึงยัง (เว้นแต่ฉันจะพลาดมัน) ก็คือteeคำสั่งยังสามารถเขียนไปยังหลายไฟล์พร้อมกัน ตัวอย่างเช่น:

ls *.png | tee a.txt b.txt

จะเขียน*.pngไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันไปยังสองไฟล์ที่แตกต่างกัน ( a.txtและb.txt) พร้อมกัน

ในความเป็นจริงคุณสามารถพิมพ์ข้อความไปยังไฟล์หลาย ๆ ไฟล์พร้อมteeกันดังนี้:

$ tee --append a.txt b.txt c.txt d.txt
These lines are appended to four different files,
and are also written to stdout.
CTRL-D

9

การใช้งานทีพบบ่อยที่สุดของทีก็คือการเห็นข้อความบนเครื่องในเวลาเดียวกันกับที่คุณส่งไปยังไฟล์ (หรือไฟล์) ข้อความของคำถามของคุณจะถือว่าคุณเขียนข้อความลงในไฟล์บันทึกเท่านั้น ฉันมีสคริปต์ที่เขียนรายการชื่อไฟล์หรือชื่อไดเรกทอรีเพื่อเรียกใช้ไฟล์ (จะถูกประมวลผลโดยสคริปต์อื่นแบบอะซิงโครนัส) และฉันใช้ tee เพื่อส่งเนื้อหาเดียวกันไปยัง stdout stdout ทั้งหมดถูกนำไปยังบันทึก ดังนั้นฉันมีข้อความของฉันที่ฉันต้องการและมีบันทึกรายการที่ฉันทำสิ่งนี้ทั้งหมดจากคำสั่ง 'echo' เดียว

ทีก็เป็นวิธีที่ดีที่สุดใน Unix สำหรับการสร้างไฟล์ที่เหมือนกันหลาย ๆ ไฟล์ ฉันใช้มันเป็นครั้งคราวเพื่อสร้างไฟล์เปล่าหลายไฟล์เช่นนี้ ...

:|tee file01 file02 file03

5
ทำไมไม่touch? (ชัดเจนยิ่งขึ้นในทันทีว่าเกิดอะไรขึ้น)
Attie

@Attie touchจะไม่ตัดไฟล์หากมีอยู่แล้ว แต่อัพเดตเวลาและบันทึกเนื้อหาตามที่เป็นอยู่เท่านั้น แต่teeจะตัดทอนพวกเขา นอกจากนี้การทำrm+ touchมีความแตกต่างกว่าtee(คิดเกี่ยวกับ hardlinks และ symlinks)
Matija Nalis

แล้วทำไมไม่truncate -s 0? :-)
Attie

1

ลองนึกภาพคุณต้องการเขียนผลลัพธ์ของคำสั่งไปยังล็อกไฟล์และพิมพ์ไปยัง stdout teeเมื่อคุณต้องการที่จะทำมันในเวลาเดียวกันแล้วคุณจะต้อง

กรณีการใช้งานคือการสร้างสคริปต์ที่เขียนบิลด์ทั้งหมดไปยัง stdout (เช่นสำหรับเจนกินส์) แต่สิ่งสำคัญในเวลาเดียวกันไปยังไฟล์บันทึกแยกต่างหาก (สำหรับอีเมลสรุป)

คุณจะเริ่มหายไปจริงๆteeเมื่อคุณต้องสคริปต์ใน Windows ไม่มีteeและน่ารำคาญจริงๆ


มันไม่สำคัญที่จะสร้างใช่ไหม
การแข่งขัน Lightness ใน Orbit

มันเป็นไปไม่ได้ด้วย batch / cmd เนื่องจากคุณไม่สามารถแยกกระแสของเอาต์พุตจากคำสั่งได้อย่างง่ายดาย
domih

ถูกต้อง แต่ก็เหมือนโปรแกรม C ++ สามบรรทัด ...
Lightness Races ใน Orbit

1
การกระจาย Windows unxutils มีเครื่องมือบรรทัดคำสั่ง Unix จำนวนมากซึ่งไม่เหมือนกับการกระจายบางอย่างซึ่งไม่ก่อให้เกิดมลพิษต่อสภาพแวดล้อมการทำงานของ Windows ของคุณ ข้อ จำกัด ที่ใหญ่ที่สุดคือ "glob" bing ซึ่งทำงานบน Unix / Linux แตกต่างจาก Windows "tee" เป็นหนึ่งในเครื่องมือที่มีให้
cmm

2
อย่าโง่มันเป็นปี 2018 ใช้ Powershell teeก็มี Cmd ไม่เคยตั้งใจทำสคริปต์อย่างจริงจัง - นั่นคือสิ่งที่ VBS ใช้ Powershell เป็นเครื่องมือการเขียนสคริปต์แบบไปที่ใหม่ จริงอยู่ที่ Cmd ยังทรงพลัง แต่เครื่องมือบรรทัดคำสั่งนั้นค่อนข้างน้อย
Luaan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.