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

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

4
วิธีทำความเข้าใจท่อ
เมื่อฉันใช้ไปป์ในการทุบตีฉันไม่ได้คิดถึงเรื่องนี้มากขึ้น แต่เมื่อฉันอ่านตัวอย่างรหัส C โดยใช้ system call pipe () ร่วมกับ fork () ฉันสงสัยว่าจะเข้าใจไพพ์ได้อย่างไรรวมถึงไพพ์นิรนามและไพพ์ที่มีชื่อ มักจะได้ยินว่า "ทุกอย่างใน Linux / Unix เป็นไฟล์" ฉันสงสัยว่าไพพ์เป็นไฟล์จริงหรือไม่เพื่อให้ส่วนหนึ่งเชื่อมต่อการเขียนไปยังไฟล์ไพพ์และอีกส่วนหนึ่งอ่านจากไฟล์ไพพ์หรือไม่ ถ้าใช่ไฟล์ไพพ์ของไพพ์นิรนามจะถูกสร้างขึ้นที่ไหน? ใน / tmp, / dev หรือ ... ? อย่างไรก็ตามจากตัวอย่างของ pipes ที่มีชื่อฉันยังได้เรียนรู้ว่าการใช้ไพพ์มีข้อได้เปรียบด้านพื้นที่และเวลามากกว่าการใช้ไฟล์ชั่วคราวอย่างชัดเจนอาจเป็นเพราะไม่มีไฟล์ที่เกี่ยวข้องในการใช้ไพพ์ ท่อดูเหมือนจะไม่เก็บข้อมูลเช่นเดียวกับไฟล์ ดังนั้นฉันจึงสงสัยว่าไพพ์เป็นไฟล์จริงๆ

2
หมดเวลา, ทำลายท่อและห้องสุขา
ฉันมีความคิดที่จะเปรียบเทียบโปรแกรมบีบอัดข้อมูลอย่างรวดเร็ว เช่นสำหรับ gz ฉันจะเรียกใช้คำสั่ง: timeout 10 zcat foo.gz | wc -c ซึ่งจะวัดปริมาณข้อมูลที่ตัวขยายการบีบอัดสามารถแยกได้ใน 10 วินาที ปัญหาเดียวก็คือว่ามันใช้งานไม่ได้: เนื่องจาก zcat ถูกฆ่า, wc ก็ถูกฆ่าด้วยดังนั้นฉันจึงไม่ได้รับจำนวนไบต์เพียงแค่Terminatedข้อความ ดังนั้นคำถามคือ: มีวิธีที่จะได้รับการนับจาก wcโดยการปิดกั้นสัญญาณอย่างใดอย่างหนึ่งหรือใช้ทางเลือกแทน wc ที่พิมพ์ผลแม้ว่ามันจะได้รับสัญญาณระยะ แน่นอนว่ามีทางเลือกอื่น ๆ : การเขียนไปยังไฟล์ชั่วคราว: timeout 10 zcat foo.gz &gt; /dev/shm/x ; du -sb /dev/shm/x ; rm -r /dev/shm/x ปัญหาที่เกิดขึ้นคือใช้หน่วยความจำจำนวนมากและอาจมีการปรับประสิทธิภาพบางอย่าง การใช้ ulimit แทน: ulimit -t 10; …
20 pipe  timeout 

3
ไปป์ที่ไม่มีบัฟเฟอร์ที่บล็อกชื่อ?
ฉันกำลังมองหาสิ่งที่ฉันสงสัยว่าไม่มีอยู่: ไปป์บัฟเฟอร์ที่ไม่มีชื่อ (Fifo) ที่ไม่มีการบล็อกเพื่อใช้งานจากบรรทัดคำสั่ง มีอะไรแบบนี้เหรอ? นี่คือกรณีการใช้งาน: stdoutสมมติว่าฉันมีกระบวนการที่จะไปทำงานเป็นเวลานานในพื้นหลังและคายจำนวนมากของการส่งออกไปยัง ฉันไม่สนใจจริง ๆ เกี่ยวกับผลลัพธ์และไม่ต้องการเก็บไว้ (บางทีฉันไม่มีพื้นที่เพียงพอที่จะ) แต่ฉันต้องการ "ปล่อย" เป็นระยะ ๆ และทำตามสิ่งที่มันทำแล้วเลื่อนออกอีกครั้ง และปล่อยให้มันทำงาน ดังนั้นฉันต้องการที่จะเปลี่ยนเส้นทางการส่งออกไปยังบัฟเฟอร์ที่มีชื่อตามทฤษฎีซึ่งไม่มีการปิดกั้นจากนั้นแตะเป็นระยะ ๆ โดยพื้นฐานแล้วฉันต้องการเริ่มต้นเช่นนี้ ( 10Mเป็นขนาดของบัฟเฟอร์): mkmagicfifo magicfifo 10M spewingprocess &gt; magicfifo &amp; ... และแวะเข้าไปเป็นระยะเพื่อดูว่าเกิดอะไรขึ้น ... tail -f magicfifo ... โดยไม่ต้อง magicfifoเก็บเอาท์พุททั้งหมด (ดังนั้นไม่ใช่ไฟล์ปกติ) และไม่มีการปิดกั้นกระบวนการที่ทำให้เกิดการระเบิดเมื่อมันเต็มและไม่ได้ถูกทาบทาม (ดังนั้นไม่ใช่ไปป์ปกติที่มีชื่อ) ฉันไม่คิดว่าวิธีแก้ปัญหาที่เกี่ยวข้องtailหรือpruneจะทำ (ดีฉันสามารถคิดถึงวิธีแก้ปัญหาที่เกี่ยวข้องtail) เพราะtailจะยังคงต้องการให้ฉันเก็บข้อมูลทั้งหมดที่ไหนสักแห่ง (ถ้าฉันต้องการที่จะลดลงและออกจากการดู) และpruneจะต้องเขียนไฟล์ใหม่อีกครั้งสันนิษฐาน (ฉันจะยอมรับว่าฉันไม่ได้ลอง / พิสูจน์ได้) ทำลายการเปลี่ยนเส้นทางของกระบวนการที่สร้างผลลัพธ์ทั้งหมด …

3
grep ไม่ส่งออกจนกว่า EOF หากส่งผ่าน cat
รับตัวอย่างที่น้อยที่สุดนี้ ( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; ) มันจะออกผลลัพธ์LINE 1และแล้วหลังจากที่สองเอาท์พุทLINE 2, คาดว่าเป็น ถ้าเราไปป์นี้ให้ได้ grep LINE ( echo "LINE 1" ; sleep 1 ; echo "LINE 2" ; ) | grep LINE พฤติกรรมจะเหมือนกับในกรณีก่อนหน้าตามที่คาดไว้ หากอีกวิธีหนึ่งเราจะทำสิ่งนี้เพื่อ cat ( echo "LINE 1" ; sleep 1 ; echo "LINE …
19 bash  grep  pipe 

2
วิธียกเลิกคำสั่ง Linux โดยไม่ทำลายแอปพลิเคชันที่ได้รับ
ฉันมีสคริปต์ทุบตีที่ทำงานตราบใดที่เครื่อง Linux เปิดอยู่ ฉันเริ่มมันดังแสดงด้านล่าง: ( /mnt/apps/start.sh 2&gt;&amp;1 | tee /tmp/nginx/debug_log.log ) &amp; หลังจาก lauches ฉันสามารถดูคำสั่ง tee ในเอาต์พุตpsของฉันได้ดังแสดงด้านล่าง $ ps | grep tee 418 root 0:02 tee /tmp/nginx/debug_log.log 3557 root 0:00 grep tee ฉันมีฟังก์ชั่นที่ตรวจสอบขนาดของบันทึกที่teeสร้างและฆ่าคำสั่งteeเมื่อบันทึกถึงขนาดที่แน่นอน: monitor_debug_log_size() { ## Monitor the file size of the debug log to make sure it does not …
19 linux  scripting  pipe  kill  tee 

4
ฉันจะใช้การไหลเวียนของข้อมูลแบบวงกลมในคำสั่งที่เชื่อมต่อระหว่างกันได้อย่างไร
ฉันรู้ว่ามีสองประเภทวิธีที่คำสั่งสามารถเชื่อมต่อซึ่งกันและกัน: โดยใช้ Pipe (วาง std-output ลงใน std-input ของคำสั่งถัดไป) โดยใช้ Tee (แบ่งเอาต์พุตเป็นเอาต์พุตจำนวนมาก) ฉันไม่ทราบว่านั่นคือทั้งหมดที่เป็นไปได้หรือไม่ดังนั้นฉันวาดประเภทการเชื่อมต่อสมมุติ: เป็นไปได้อย่างไรที่จะใช้การไหลเวียนของข้อมูลระหว่างคำสั่งเช่นในรหัสเทียมนี้ซึ่งฉันใช้ตัวแปรแทนคำสั่ง: pseudo-code: a = 1 # start condition repeat { b = tripple(a) c = sin(b) a = c + 1 }

3
ปัญหา readarray (หรือ pipe)
ฉันติดอยู่กับพฤติกรรมแปลก ๆ ของการreadarrayออกคำสั่ง man bashฯ : readarray Read lines from the standard input into the indexed array variable array แต่สคริปต์เหล่านี้ไม่ทำงาน (อาร์เรย์ว่างเปล่า): unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]} unset arr; cat /etc/passwd | readarray arr; echo ${#arr[@]} และงานเหล่านี้: unset arr; readarray arr &lt; /etc/passwd …
19 bash  pipe 

3
ใช้ ^ เป็นตัวบ่งชี้เชลล์
ฉันเขียนสคริปต์เล็ก ๆ วันนี้ซึ่งมี grep -q ^local0 /etc/syslog.conf ในระหว่างการตรวจสอบผู้ร่วมงานแนะนำ^local0ให้เสนอราคาเพราะ^หมายถึง "ท่อ" ในเชลล์เป้าหมาย ฉันได้พยายามติดตามข้อมูลอ้างอิงที่กล่าวถึงสิ่งนี้ ไม่พบสิ่งใดบนอินเทอร์เน็ตที่แนะนำว่านี่เป็นปัญหา อย่างไรก็ตามปรากฎว่าการใช้งานbsh(ซึ่งอ้างว่าเป็นเชลล์เป้าหมาย) บน AIX 7 มีลักษณะการทำงานนี้: &gt; bsh $ ls ^ wc 23 23 183 $ ls | wc 23 23 183 ไม่มีการใช้งาน "บอร์นเชลล์" อื่นใดที่ฉันพยายามทำในลักษณะนี้ (นั่น^คือไม่ถือว่าเป็นเชลล์เมตาอักขระเลย) ฉันลองใช้shCentOS (ซึ่งทุบตีจริงๆ) และshFreeBSD (ซึ่งไม่ใช่ทุบตี) ฉันไม่มีระบบอื่น ๆ ให้ลอง พฤติกรรมนี้คาดหวังหรือไม่? เชลล์ตัวไหนที่คิดว่า^เป็นตัวชี้ตำแหน่งท่อ?

4
ทำไมบางคำสั่งไม่อ่านจากอินพุตมาตรฐาน?
ฉันสงสัยว่าเมื่อไหร่ที่เราควรใช้ไปป์ไลน์และเมื่อใดที่เราไม่ควรทำ พูดเช่นเพื่อฆ่ากระบวนการบางอย่างที่จัดการไฟล์ pdf ข้อมูลต่อไปนี้จะไม่ทำงานโดยใช้ไปป์ไลน์: ps aux | grep pdf | awk '{print $2}'|kill แต่เราสามารถทำได้ด้วยวิธีต่อไปนี้เท่านั้น: kill $(ps aux| grep pdf| awk '{print $2}') หรือ ps aux | grep pdf | awk '{print $2}'| xargs kill อ้างอิงจากman bash(เวอร์ชั่น4.1.2): The standard output of command is connected via a pipe to the standard input …
19 shell  pipe  arguments  stdin 

3
echo vs <<< หรือใช้ echo ใน Bash Award อย่างไร้ประโยชน์?
โดยตอนนี้ใช้ประโยชน์ของcatรางวัลเป็นที่รู้จักกันเป็นอย่างดีและยังมีการเอ่ยถึงการใช้ประโยชน์ของecho (ไม่เกี่ยวข้องกับคำถามนี้) ฉันสงสัยว่าควรจะมี "การใช้งานไร้ประโยชน์echoในรางวัล Bash": การวางท่อดูเหมือนจะช้ากว่า heredocs และ herestrings มากตามการวัดทางวิทยาศาสตร์บางอย่าง: Heredocs: for reps in 1 2 3 do time for i in {1..1000} do cat &lt;&lt;'END' test string END done &gt; /dev/null done real 0m1.786s user 0m0.212s sys 0m0.332s real 0m1.817s user 0m0.232s sys 0m0.332s real 0m1.846s user 0m0.256s sys …

1
ทำไมการส่งท่อ `tar 'ลงใน` dd' ไม่หยุดจนกว่าดิสก์จะเต็ม
ฉันมีไฟล์เก็บถาวร tar ของดิสก์อิมเมจเดียว ภาพภายในไฟล์ tar นี้มีขนาดประมาณ 4GB ฉันไพพ์เอาท์พุทของtar xfไปddยังเพื่อเขียนดิสก์อิมเมจไปยังการ์ด SD diskdump ไม่เคยหยุดจนกว่าการ์ดจะเต็ม นี่คือเซสชันเชลล์ของฉัน: $ ls -l disk.img.tgz -rw-r--r-- 1 confus confus 192M Okt 5 00:53 $ tar -tvf disk.img.tgz -rw-r--r-- root/root 4294968320 2018-10-05 00:52 disk.img $ lsblk -lb /dev/sdc NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sdc 8:32 1 16022241280 …
18 pipe  tar  dd  disk-image 


2
วิธีการเขียนฟังก์ชั่นทุบตีโดยใช้ท่อ?
ฉันมีฟังก์ชั่นบางอย่างที่กำหนดไว้ในแบบนี้: function f { read and process $1 ... echo $result } ฉันต้องการที่จะประกอบมันเข้าด้วยกันเพื่อที่การภาวนาจะเป็นเช่นf | g | hนั้น ฉันใช้สำนวนอะไรในการแปลงฟังก์ชั่นที่ทำงานกับข้อโต้แย้งเป็นหนึ่งข้อโต้แย้งการอ่านจาก stdin? เป็นไปได้ไหมที่จะอ่านคู่ tuples ของการขัดแย้งจากกระแสโดยไม่จำเป็นต้องหลบหนีพวกมัน (เช่นการยกเลิก null)?

3
จะดาวน์โหลดแพ็คเกจ RPM และติดตั้งในหนึ่งบรรทัดได้อย่างไร
ฉันสงสัยว่าการใช้งานwgetเป็นไปได้หรือไม่ที่จะดาวน์โหลด RPM และต่อท่อsudo rpm -iไปยังการติดตั้งในบรรทัดเดียว? ฉันรู้ว่าฉันสามารถวิ่งได้: wget -c &lt;URL&gt; sudo rpm -i &lt;PACKAGE-NAME&gt;.rpm เพื่อติดตั้งแพ็คเกจ แต่ฉันสงสัยว่ามันอาจเป็นไปได้ที่จะทำในบรรทัดเดียวโดยใช้ความเงียบและเขียนไปยังตัวเลือกเอาต์พุตมาตรฐานของ wget ฉันได้ลองใช้: wget -cqO- &lt;URL&gt; | sudo rpm -i แต่มันกลับมา: rpm: no packages given for install
18 pipe  rpm  wget 

4
ส่งออกไปยัง stdout และในเวลาเดียวกัน grep เป็นไฟล์
stdoutฉันมีสคริปต์ที่ข้อความขาออกไป ฉันต้องการที่จะเห็นผลลัพธ์ทั้งหมดนี้ใน terminal ของฉันและในเวลาเดียวกันฉันต้องการที่จะกรองบางบรรทัดและบันทึกไว้ในไฟล์ ตัวอย่าง: $ myscript Line A Line B Line C $ myscript | grep -P 'A|C' &gt; out.file $ cat out.file Line A Line C ฉันต้องการเห็นเอาต์พุตของคำสั่งแรกในเทอร์มินัลและบันทึกผลลัพธ์ของคำสั่งที่สองในไฟล์ ในเวลาเดียวกัน. ฉันพยายามใช้teeแต่ไม่มีผลกับหรือดีกว่ามีผลตรงกันข้าม
18 grep  pipe  stdout  tee 

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