คำถามติดแท็ก pipe

ไปป์ Unix เชื่อมต่อตัวอธิบายไฟล์ของสองกระบวนการ ไปป์ถูกสร้างขึ้นด้วยฟังก์ชัน POSIX pipe () ที่ประกาศใน <unistd.h> เชลล์จัดเตรียมการสร้างไพพ์ระหว่างกระบวนการโดยใช้ "|"

6
ไพพ์ไปยังหลายไฟล์ในเชลล์
ฉันมีแอปพลิเคชั่นซึ่งจะสร้างข้อมูลจำนวนมากซึ่งฉันไม่ต้องการจัดเก็บลงดิสก์ แอปพลิเคชั่นส่วนใหญ่ส่งออกข้อมูลที่ฉันไม่ต้องการใช้ แต่เป็นชุดข้อมูลที่มีประโยชน์ที่ต้องแยกเป็นไฟล์แยกต่างหาก ตัวอย่างเช่นกำหนดเอาต์พุตต่อไปนี้: JUNK JUNK JUNK JUNK A 1 JUNK B 5 C 1 JUNK ฉันสามารถเรียกใช้แอปพลิเคชันได้สามครั้งดังนี้: ./app | grep A &gt; A.out ./app | grep B &gt; B.out ./app | grep C &gt; C.out นี่จะทำให้ฉันได้สิ่งที่ฉันต้องการ แต่ใช้เวลานานเกินไป ฉันไม่ต้องการดัมพ์เอาต์พุตทั้งหมดไปยังไฟล์เดียวและวิเคราะห์คำนั้น มีวิธีใดบ้างที่จะรวมการดำเนินการทั้งสามที่แสดงไว้ด้านบนในลักษณะที่ฉันจะต้องเรียกใช้แอปพลิเคชันเพียงครั้งเดียวและยังคงได้รับไฟล์เอาต์พุตสามไฟล์
29 bash  shell  grep  pipe 

4
มีวิธีการไพพ์เอาต์พุตของหนึ่งโปรแกรมเป็นสองโปรแกรมอื่นหรือไม่?
ขออภัยถ้านี่เป็นคำถามงี่เง่า แต่ฉันพยายามทำสิ่งนี้ แต่ในบรรทัดเดียว: $ prog1 | prog2 $ prog1 | prog3 ดังนั้นโดยทั่วไปฉันต้องการดำเนินการ prog1 และไพพ์เอาต์พุตไปยัง prog2 และ prog3 แยกจากกัน (ไม่ใช่ไปป์ที่ถูกล่ามโซ่) ตอนแรกฉันพยายามใช้ tee แต่มันดูไม่ถูกต้องเพราะมันถูกทิ้งเอาท์พุทไปยังไฟล์ (ซึ่งไม่ใช่สิ่งที่ฉันต้องการ) $ prog1 | tee prog2 | prog3 # doesn't work - creates file "prog2" ในบางจุดฉันอาจต้องการขยายสิ่งนี้ไปยัง piping output ไปมากกว่าสองโปรแกรม แต่ตอนนี้ฉันเพิ่งเริ่มง่าย $ prog1 | prog2 $ prog1 | prog3 …
28 pipe 

1
เหตุใดไฟล์ echo> ใช้เวลาจริงมากกว่า echo | sed> file?
ตัวอย่างด้านล่างทำให้ฉันประหลาดใจ ดูเหมือนว่าจะตอบโต้ได้ง่าย ... นอกเหนือจากความจริงที่ว่ามีเวลาผู้ใช้มากขึ้นสำหรับecho | sedคอมโบ เหตุใดจึงechoใช้เวลามากเมื่อทำงานเพียงอย่างเดียวหรือคำถามควรsedเปลี่ยนสถานะการเล่นอย่างไร ดูเหมือนว่าechoจะต้องทำเสียงสะท้อนที่เหมือนกันในทั้งสองกรณี ... time echo -n a\ {1..1000000}\ c$'\n' &gt;file # real 0m9.481s # user 0m5.304s # sys 0m4.172s time echo -n a\ {1..1000000}\ c$'\n' |sed s/^\ // &gt;file # real 0m5.955s # user 0m5.488s # sys 0m1.580s
28 bash  shell  pipe  time  echo 

6
เหตุใดฉันจึงไม่สามารถเปลี่ยนเส้นทางชื่อผลลัพธ์จากคำสั่งเดียวไปยัง“ cd” ได้
ฉันพยายามรับcdชื่อไดเรกทอรีที่เปลี่ยนเส้นทางจากคำสั่งอื่น วิธีการเหล่านี้ไม่ทำงาน: $ echo $HOME | cd $ echo $HOME | xargs cd วิธีนี้ใช้ได้ผล: $ cd $(echo $HOME) ทำไมชุดคำสั่งแรกไม่ทำงานและมีคำสั่งอื่นที่ล้มเหลวด้วยหรือไม่

5
วิธีประมวลผล / ไพพ์เอาต์พุต TCPDUMPs แบบเรียลไทม์
ถ้าฉันต้องการที่จะ tcpdump ร้องขอ DNS โดยลูกค้า (บนเราเตอร์ OpenWrt 10.04) จากนั้นฉัน root@ROUTER:/etc# tcpdump -n -i br-lan dst port 53 2&gt;&amp;1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on br-lan, link-type EN10MB (Ethernet), capture size 96 bytes 22:29:38.989412 IP 192.168.1.200.55919 &gt; 192.168.1.1.53: 5697+ A? foo.org. (25) 22:29:39.538981 …
27 pipe  tcpdump 

3
ฉันจะจับเวลาท่อได้อย่างไร
ฉันต้องการtimeคำสั่งที่ประกอบด้วยคำสั่งสองคำสั่งแยกกันโดยมีหนึ่ง piping output ไปยังอีกคำสั่งหนึ่ง ตัวอย่างเช่นพิจารณาสองสคริปต์ด้านล่าง: $ cat foo.sh #!/bin/sh sleep 4 $ cat bar.sh #!/bin/sh sleep 2 ตอนนี้ฉันtimeจะรายงานเวลาที่ใช้ไปได้อย่างไรfoo.sh | bar.sh(และใช่ฉันรู้แล้วว่าไพพ์ไม่มีความหมายที่นี่ แต่นี่เป็นเพียงตัวอย่าง) มันทำงานได้อย่างที่คาดไว้ถ้าฉันใช้มันต่อเนื่องใน subshell โดยไม่ต้อง piping: $ time ( foo.sh; bar.sh ) real 0m6.020s user 0m0.010s sys 0m0.003s แต่ฉันไม่สามารถทำให้มันทำงานได้เมื่อ piping: $ time ( foo.sh | bar.sh ) real 0m4.009s user 0m0.007s …
27 bash  shell  pipe  time 

8
การขยายท่อการเลื่อนหรือการเพิ่มประสิทธิภาพมีประสิทธิภาพมากขึ้นหรือไม่?
ฉันกำลังพยายามหาวิธีที่มีประสิทธิภาพมากที่สุดในการวนซ้ำค่าบางค่าซึ่งเป็นค่าที่สอดคล้องกันซึ่งอยู่ห่างกันในรายการคำที่คั่นด้วยช่องว่าง (ฉันไม่ต้องการใช้อาร์เรย์) ตัวอย่างเช่น, list="1 ant bat 5 cat dingo 6 emu fish 9 gecko hare 15 i j" ดังนั้นฉันต้องการที่จะสามารถวนซ้ำในรายการและเข้าถึง 1,5,6,9 และ 15 เท่านั้น แก้ไข:ฉันควรทำให้ชัดเจนว่าค่าที่ฉันพยายามรับจากรายการไม่ต้องแตกต่างในรูปแบบจากส่วนที่เหลือของรายการ สิ่งที่ทำให้พวกเขาพิเศษเป็นเพียงตำแหน่งของพวกเขาในรายการ (ในกรณีนี้ตำแหน่ง 1,4,7 ... ) ดังนั้นรายการอาจเป็นได้1 2 3 5 9 8 6 90 84 9 3 2 15 75 55แต่ฉันยังต้องการหมายเลขเดิม และฉันต้องการที่จะทำมันโดยสมมติว่าฉันไม่รู้ความยาวของรายการ วิธีการที่ฉันเคยคิดคือ: วิธีที่ 1 set $list …

1
ทำไม 'sed q' ทำงานแตกต่างกันเมื่ออ่านจากไปป์
คำถามนี้ถูกโยกย้ายจาก Server Fault เนื่องจากสามารถตอบได้ใน Unix &amp; Linux Stack Exchange อพยพ 3 ปีที่แล้ว ฉันสร้างไฟล์ทดสอบชื่อ 'ทดสอบ' ที่มีสิ่งต่อไปนี้: xxx yyy zzz ฉันรันคำสั่ง: (sed '/y/ q'; echo aaa; cat) &lt; test และฉันได้รับ: xxx yyy aaa zzz จากนั้นฉันก็วิ่ง: cat test | (sed '/y/ q'; echo aaa; cat) และได้รับ: xxx yyy aaa คำถาม sedอ่านและพิมพ์จนกว่าจะพบบรรทัดที่มี 'y' จากนั้นหยุด …
25 sed  pipe 

2
วิธีการพกพา (POSIX) เพื่อให้เกิดการทดแทนกระบวนการคืออะไร?
เชลล์บางตัวbashสนับสนุนการทดแทนกระบวนการซึ่งเป็นวิธีการนำเสนอผลลัพธ์กระบวนการเป็นไฟล์เช่นนี้: $ diff &lt;(sort file1) &lt;(sort file2) อย่างไรก็ตามโครงสร้างนี้ไม่ใช่POSIXและไม่ใช่พกพา วิธีสามารถดำเนินการเปลี่ยนตัวทำได้ในPOSIXลักษณะที่เป็นมิตร (เช่นหนึ่งซึ่งทำงาน/bin/sh) ? หมายเหตุ: คำถามไม่ได้ถามว่าจะแตกไฟล์ที่จัดเรียงสองไฟล์ได้อย่างไรซึ่งเป็นเพียงตัวอย่างที่ประดิษฐ์ขึ้นเพื่อสาธิตการทดแทนกระบวนการ !

1
ท่อทำงานอย่างไรใน Linux
ฉันได้อ่านเกี่ยวกับวิธีการใช้ไพพ์ในเคอร์เนล Linux และต้องการตรวจสอบความเข้าใจของฉัน หากฉันไม่ถูกต้องคำตอบพร้อมคำอธิบายที่ถูกต้องจะถูกเลือก Linux มี VFS เรียกว่า pipefs ที่ติดตั้งในเคอร์เนล (ไม่ใช่ในพื้นที่ผู้ใช้) pipefs มีซุปเปอร์บล็อกเดียวและติดตั้งที่รูทของมันเอง ( pipe:) ข้างๆ/ pipefs ไม่สามารถดูได้โดยตรงเหมือนกับระบบไฟล์ส่วนใหญ่ รายการไปยัง pipefs คือผ่านpipe(2)syscall pipe(2)syscall ใช้โดยเปลือกหอยสำหรับท่อกับ|ผู้ประกอบการ (หรือด้วยตนเองจากกระบวนการอื่น ๆ ) สร้างไฟล์ใหม่ใน pipefs ซึ่งทำงานสวยมากเช่นไฟล์ปกติ ไฟล์ทางด้านซ้ายของผู้ประกอบการไปป์ได้stdoutถูกเปลี่ยนเส้นทางไปยังไฟล์ชั่วคราวที่สร้างขึ้นใน pipefs ไฟล์ทางด้านขวาของผู้ปฏิบัติงานไปป์มี stdinไพพ์ตั้งค่าไฟล์ไว้ที่ pipefs pipefs ถูกเก็บไว้ในหน่วยความจำและผ่านเคอร์เนลเวทย์มนตร์บางอย่างไม่ควรทำเพจ นี่คือคำอธิบายว่าท่ออย่างไร (เช่น ls -la | less ) ว่าถูกต้องหรือไม่? สิ่งหนึ่งที่ผมไม่เข้าใจคือวิธีการบางอย่างเช่นทุบตีจะตั้งเป็นกระบวนการstdinหรือจะอธิบายไฟล์ที่ส่งกลับโดยstdout pipe(2)ฉันยังไม่พบอะไรเกี่ยวกับสิ่งนั้น
25 kernel  pipe 

1
ฉันจะเปลี่ยนทิศทางผลลัพธ์การเสร็จสิ้นคำสั่งได้อย่างไร
ในบรรทัดคำสั่งฉันสามารถเปลี่ยนเส้นทางหรือไพพ์เอาท์พุทของคำสั่งไปยังไฟล์หรือคำสั่งอื่นโดยใช้ตัวดำเนินการ&gt;หรือ|หลังคำสั่ง ฉันเจอสถานการณ์มาตรฐานน้อยกว่าที่ฉันต้องการเปลี่ยนเส้นทางผลลัพธ์ไปยังไฟล์ แต่ดูเหมือนว่าฉันไม่มีโอกาสได้เปลี่ยนเส้นทาง: เมื่ออยู่ที่อาคารผู้โดยสารแห่งใหม่ [chiliNUT ~]$ ถ้าฉันกดTabโดยไม่พิมพ์อะไรก่อนฉันจะถูกถาม display all 1725 possibilities? (y or n) และถ้าฉันพิมพ์yฉันก็จะได้คำสั่งต่าง ๆ จำนวนมาก ฉันจะเปลี่ยนเส้นทางหรือไพพ์เอาต์พุตนี้ไปยังไฟล์ได้อย่างไร? ฉันดูเหมือนจะไม่ได้รับโอกาสในการพิมพ์&gt; myfile.txtทุกที่ ใช้CentOS ปล่อย 6.4 (สุดท้าย)

3
ติดตามท่อโดยใช้น้อยลงหรือไม่
สามารถติดตามน้อยลง (โดยกด F) อินพุต piped (คล้ายกับไฟล์) ได้หรือไม่? สำหรับไฟล์ที่กำลังถูกเขียนไปยังคำสั่ง less &lt;file&gt; จะติดตามไฟล์เมื่อกด F แต่ถ้าฉันมีคำสั่งที่ไพพ์เอาต์พุตโดยตรงให้น้อยลงเช่นนี้ command | less การกด F จะไม่ทำอะไรเลย ดังนั้นดูเหมือนว่าไม่สามารถติดตามท่อเหมือนไฟล์ได้หรือไม่ หรือบางทีมันอาจจะเกี่ยวข้องกับคำสั่งที่เขียนถึง STDERR ด้วย เอฟเฟกต์ที่ฉันพยายามจะบรรลุนั้นจะเห็นผลลัพธ์ล่าสุดของคำสั่งเช่นเดียวกับที่กด PageDown ค้างไว้! คำพูดที่เกี่ยวข้องมีไว้สำหรับ G (ไปที่จุดสิ้นสุด): เมื่อการไพพ์โดยตรงไปที่น้อยกว่ามันจะไม่ทำงาน
25 pipe  less  tail 


4
เหตุใดตัวแปรภายในของฉันจึงอยู่ใน 'ขณะที่อ่าน' แต่ไม่ใช่ในวงอื่นที่คล้ายกัน
เหตุใดฉันจึงได้รับค่าต่าง ๆ$xจากตัวอย่างด้านล่าง #!/bin/bash x=1 echo fred &gt; junk ; while read var ; do x=55 ; done &lt; junk echo x=$x # x=55 .. I'd expect this result x=1 cat junk | while read var ; do x=55 ; done echo x=$x # x=1 .. but why? x=1 echo fred …

2
วิธีการจับภาพสั่ง STDOUT / STDERR และเพิ่มการประทับเวลา / คำนำหน้า?
ฉันได้สำรวจคำถามที่คล้ายกันเกือบทั้งหมดที่ มีอยู่ แล้วเพื่อประโยชน์ ให้ฉันอธิบายปัญหาโดยละเอียด: ฉันรันสคริปต์ที่ไม่ต้องใส่ข้อมูลบางส่วนและสิ่งเหล่านี้สามารถสร้างเอาต์พุตมาตรฐานและบรรทัดข้อผิดพลาดมาตรฐานได้ฉันต้องการจับภาพพวกเขาตามลำดับที่ถูกต้องตามที่แสดงโดยเทอร์มินัลอีมูเลเตอร์แล้วเพิ่มคำนำหน้าเช่น "STDERR:" และ "STDOUT:" ฉันได้ลองใช้ไพพ์และแม้กระทั่งวิธีที่อิงจากพวกมันเพื่อประโยชน์แล้ว ฉันคิดว่าวิธีการแก้ปัญหาคือการใช้ pty แม้ว่าฉันจะไม่มีความเชี่ยวชาญในเรื่องนั้น ฉันได้แอบมองเข้าไปในซอร์สโค้ดของVTE ของ Gnomeแต่ก็ไม่ได้มีประโยชน์อะไรมาก เป็นการดีที่ฉันจะใช้Goแทน Bash เพื่อทำสิ่งนี้ แต่ฉันไม่สามารถทำได้ ดูเหมือนว่าท่อโดยอัตโนมัติห้ามการสั่งซื้อบรรทัดที่ถูกต้องเพราะบัฟเฟอร์ มีใครบางคนที่สามารถทำสิ่งที่คล้ายกันได้หรือไม่? หรือเป็นไปไม่ได้เลยเหรอ? ฉันคิดว่าถ้าเทอร์มินัลอีมูเลเตอร์สามารถทำได้มันอาจไม่ใช่ - โดยการสร้างโปรแกรม C ขนาดเล็กที่จัดการ PTY แตกต่างกันหรือไม่ นึกคิดฉันจะใช้อินพุตแบบอะซิงโครนัสเพื่ออ่านสตรีม 2 รายการ (STDOUT และ STDERR) จากนั้นพิมพ์อีกครั้งตามความต้องการของฉัน แต่ลำดับของอินพุตเป็นสิ่งสำคัญ! หมายเหตุ:ฉันทราบถึงstderredแต่มันไม่ได้ผลสำหรับฉันกับสคริปต์ Bash และไม่สามารถแก้ไขเพื่อเพิ่มคำนำหน้าได้อย่างง่ายดาย (เนื่องจากโดยทั่วไปแล้วจะมี syscalls มากมาย) อัปเดต:เพิ่มด้านล่างสองส่วน ตัวอย่างโปรแกรมที่สร้าง stdout ผสม / stderr ผลลัพธ์ที่คาดหวังจากโปรแกรมด้านบน …

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