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

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

2
เป็นไปได้ไหมที่จะทำการค้นหา () กับการส่งคืนไพพ์ที่มีชื่อสำเร็จ
มีวิธีใดบ้างที่จะทำให้โปรแกรมพยายามดำเนินseek()การกับไพพ์ที่มีชื่อมันจะกลับมาประสบความสำเร็จ (แต่ทำราวกับว่าไพพ์เป็นไฟล์เปล่า) แทนที่จะเป็น 'Illegal แสวงหา'? ฉันมีการบันทึกในระบบของฉันเล็กน้อยทุกครั้งที่เก็บไว้ในฐานข้อมูล SQLite ฉันไม่มีไฟล์ทุกที่ อย่างไรก็ตามมีบางโปรแกรมที่มีปัญหากับสิ่งนี้ มี 2 ​​กรณีที่เฉพาะเจาะจง; โปรแกรมต้องการเขียนไปยังล็อกไฟล์ซึ่ง syslog-ng ได้สร้างขึ้นเป็นไพพ์ที่มีชื่อและกำลังอ่านจาก โปรแกรมต้องการดำเนินการseek()ด้วยเหตุผลบางอย่างแล้วล้มเหลว โปรแกรม (เช่น denyhosts หรือ fail2ban) ต้องการอ่านจากไฟล์บันทึกที่ syslog-ng สร้างขึ้นเป็นไพพ์ที่มีชื่อและกำลังเขียนถึง โปรแกรมต้องการดำเนินการseek()กับมันและล้มเหลว เป็นการดีที่ฉันต้องการให้สิ่งเหล่านี้พยายามทำตัวราวกับว่าไพพ์ที่มีชื่อเป็นเพียงไฟล์ว่างเปล่า ฉันไม่เห็นเหตุผลว่าทำไมโปรแกรมที่เขียนบันทึกจะต้องทำการค้นหาต่อไปมันควรเปิดไฟล์เพื่อผนวกและเริ่มเขียน ฉันสามารถดูได้ว่าเหตุใดการอ่านของโปรแกรมจึงต้องการค้นหาเพื่อให้มันสามารถกลับมาทำงานจากตำแหน่งสุดท้ายได้ดังนั้นฉันจึงอยากให้มันทำงานเหมือนกับว่าไฟล์นั้นว่างเปล่า (เหมือนถูกตัดทอน) ดังนั้นมีตัวเลือกที่สามารถตั้งค่าบน pipes ชื่อเพื่อให้พวกเขาทำงานแบบนี้? หากไม่มีโหมดที่สามารถตั้งค่าได้เมื่อ syslog-ng เปิดไปป์เพื่อให้มันทำงานแบบนี้ (ฉันเปิดเพื่อทำการเปลี่ยนแปลงรหัส)? หรือว่าฉันเป็นห้วย
12 pipe  syslog 

3
จะทำให้ไพพ์ไลน์รอการสิ้นสุดไฟล์หรือหยุดหลังจากเกิดข้อผิดพลาดได้อย่างไร?
ฉันลองคำสั่งต่อไปนี้หลังจากดูวิดีโอนี้ใน shenanigans ไปป์ man -k . | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf | zathura - โดยทั่วไปจะพิมพ์รายการ manpages ไปที่ dmenu เพื่อให้ผู้ใช้เลือกหนึ่งรายการจากนั้นจะใช้ xargs เพื่อเรียกใช้man -Tpdf %(พิมพ์ไปยัง stdout PDF ของ manpage git จากอินพุต xargs) และส่ง pdf ไปยังโปรแกรมอ่าน pdf (zathura ) ปัญหาคือ (ตามที่คุณเห็นในวิดีโอ) ตัวอ่าน pdf เริ่มต้นก่อนที่ฉันจะเลือก manpage …

2
(และทำไม) ใช้ stderr สำหรับทั้งการอ่านและการเขียนได้อย่างไร
ตามคำตอบนี้โดย schily , lessอ่านคำสั่งนำทางจาก stderr /dev/ttyถ้ามันไม่สามารถที่จะเปิด ดูเหมือนว่าจะทำให้งงงวยเนื่องจากฉันไม่เคยเห็นสิ่งใดที่เขียนไปยังสตรีม stderr ของโปรแกรมอื่นและฉันไม่รู้ว่าฉันจะทำอย่างไรให้สำเร็จ จุดประสงค์ของ stderr ที่เปิดสำหรับการอ่านและการเขียนคืออะไร? และถ้ามันมีประโยชน์ฉันจะใช้มันกับระบบที่ทันสมัยได้อย่างไร? (มีไวยากรณ์อาร์เคนบางอย่างเพื่อไพพ์บางสิ่งลงใน stderr แทนที่จะเป็น stdin หรือไม่?)
12 pipe  stderr 

1
ท่อ“ รั่ว” ใน linux
สมมติว่าคุณมีไพพ์ไลน์ดังนี้: $ a | b หากbหยุดการประมวลผล stdin หลังจากนั้นไม่นานท่อจะเต็มและเขียนจากaไปยัง stdout จะบล็อก (จนกว่าจะbเริ่มการประมวลผลอีกครั้งหรือไม่ก็ตาย) หากฉันต้องการหลีกเลี่ยงสิ่งนี้ฉันอาจถูกล่อลวงให้ใช้ท่อขนาดใหญ่กว่า (หรือมากกว่านั้นbuffer(1)) ได้เช่น: $ a | buffer | b นี่จะซื้อเวลาให้ฉันมากขึ้น แต่ในที่สุดaก็จะหยุด สิ่งที่ฉันชอบ (สำหรับสถานการณ์ที่เฉพาะเจาะจงมากที่ฉันกำลังพูดถึง) คือการมีท่อ "รั่ว" ที่เมื่อเต็มแล้วจะลดลงข้อมูลบางส่วน (นึกคิดทีละบรรทัดโดยบรรทัด) จากบัฟเฟอร์เพื่อให้aดำเนินการต่อ การประมวลผล (อย่างที่คุณคงจินตนาการได้ว่าข้อมูลที่ไหลในไพพ์นั้นมีค่าใช้จ่ายนั่นคือการมีข้อมูลที่ประมวลผลโดยbมีความสำคัญน้อยกว่าการaวิ่งโดยไม่ปิดกั้น) เพื่อสรุปมันขึ้นมาฉันชอบที่จะมีบางสิ่งบางอย่างเช่นบัฟเฟอร์ที่มีขอบเขตและมีรอยรั่ว: $ a | leakybuffer | b ฉันอาจใช้มันได้อย่างง่ายดายในภาษาใด ๆ ฉันแค่สงสัยว่ามีบางสิ่งที่ "พร้อมใช้" (หรือบางสิ่งบางอย่างเช่นทุบตีสายการบินเดียว) ที่ฉันขาดไป หมายเหตุ: ในตัวอย่างที่ฉันใช้ไพพ์ทั่วไป แต่คำถามก็ใช้ได้กับไพพ์ที่ตั้งชื่อด้วย ในขณะที่ฉันได้รับคำตอบด้านล่างฉันก็ตัดสินใจที่จะใช้คำสั่ง leakybuffer เพราะวิธีง่ายๆด้านล่างมีข้อ …
12 linux  pipe  fifo  buffer 

2
จะเก็บไพพ์ (|) ในตัวแปรได้อย่างไร?
แนวคิดจะใช้เป็น ... ไปป์ในคำสั่ง ตัวอย่างเช่นสมมติว่ามีเส้นทางยาว ๆ ที่ต้องพิมพ์ซ้ำอีกครั้งตามด้วยไพพ์และโปรแกรมที่สองเช่น "directory1/directory2/direcotry3/file.dat | less -I " ฉันต้องการให้ส่วนนั้นถูกเก็บไว้ในตัวแปรดังนั้นจึงสามารถใช้เช่นนี้: r="directory1/directory2/direcotry3 \| less -I -p " $ cat path1/path2/$r &lt;searchterm&gt; แต่ฉันได้รับ cat: invalid option -- I Try `cat --help' for more information. ... หมายถึงท่อไม่ทำงาน
12 bash  pipe  variable 

4
netcat ไม่ตอบสนองการพิมพ์
ฉันกำลังพยายามส่งคำสั่งไปยังพอร์ต tcp โดยใช้netcatและการตอบสนองไปป์ เมื่อฉันรันnetcatและพิมพ์คำสั่งของฉันมันพิมพ์การตอบสนองอย่างถูกต้อง แต่เมื่อฉันส่งคำสั่งจากไพพ์มันจะส่งคำสั่งอย่างถูกต้อง แต่ไม่พิมพ์การตอบสนอง ดังนั้นวิธีนี้ทำงานอย่างถูกต้อง: netcat localhost 9009 ขณะนี้เพิ่งส่งคำสั่ง แต่ไม่ตอบสนองการพิมพ์: echo 'my_command' | netcat localhost 9009 ทำไม? ฉันnetcatจะพิมพ์ข้อความตอบกลับได้อย่างไร
12 pipe  netcat 

5
พบไฟล์ที่เปิดด้วยคำสั่ง 'find'
นี่อาจเป็นเรื่องง่าย แต่ฉันไม่สามารถเข้าใจได้และมันก็ไม่สามารถค้นหาได้ ในลำดับชั้นของโฟลเดอร์ฉันมีไฟล์ประเภท xyz หนึ่งไฟล์ ฉันต้องการค้นหาไฟล์นั้นและเปิดด้วยคำสั่งเทอร์มินัล find . -name *.xyz นี่จะส่งคืนไฟล์ที่ฉันกำลังค้นหา ตอนนี้ฉันจะเปิดโดยอัตโนมัติโดยไม่ต้องพิมพ์ชื่อได้อย่างไร find . -name *xyz | open มันใช้งานไม่ได้ มันบอกว่าไม่พบคำสั่งเปิด
12 linux  terminal  find  pipe 

2
ทำไมฉันถึงสูญเสียข้อมูลโดยใช้การสร้างท่อ bash นี้
ฉันกำลังพยายามรวมโปรแกรมบางโปรแกรมเช่นนั้น (โปรดละเว้นการรวมพิเศษใด ๆ นี่เป็นงานที่กำลังดำเนินการอยู่): pv -q -l -L 1 &lt; input.csv | ./repeat &lt;(nc "host" 1234) แหล่งที่มาของโปรแกรมซ้ำมีลักษณะดังนี้: #include &lt;fcntl.h&gt; #include &lt;stdint.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; #include &lt;sys/epoll.h&gt; #include &lt;sys/stat.h&gt; #include &lt;sys/types.h&gt; #include &lt;unistd.h&gt; #include &lt;iostream&gt; #include &lt;string&gt; inline std::string readline(int fd, const size_t len, const char delim = …

6
ท่อกึ่งอะซิงโครนัส
สมมติว่าฉันมีท่อต่อไปนี้: a | b | c | d ฉันจะรอให้เสร็จสิ้นการc(หรือb) ในshหรือbash? ซึ่งหมายความว่าสคริปต์dสามารถเริ่มต้นได้ตลอดเวลา (และไม่จำเป็นต้องรอ) แต่ต้องการเอาต์พุตที่สมบูรณ์จากcการทำงานอย่างถูกต้อง กรณีการใช้งานมีdifftoolไว้สำหรับgitเปรียบเทียบรูปภาพ มันถูกเรียกใช้โดยgitและต้องการประมวลผลอินพุต ( a | b | cส่วน) และแสดงผลลัพธ์ของการเปรียบเทียบ ( dส่วน) โทรจะลบการป้อนข้อมูลที่จำเป็นสำหรับการและa bซึ่งหมายความว่าก่อนที่จะส่งคืนจากสคริปต์กระบวนการc(หรือb) จะต้องยุติ ในทางกลับกันฉันไม่สามารถรอได้dเพราะนี่หมายความว่าฉันกำลังรอการป้อนข้อมูลจากผู้ใช้ ฉันรู้ว่าฉันสามารถเขียนผลของการcไปยังแฟ้มชั่วคราวหรืออาจจะใช้ FIFO bashใน (ไม่แน่ใจว่า FIFO จะช่วยได้หรือไม่) เป็นไปได้ไหมหากไม่มีไฟล์ชั่วคราวsh? แก้ไข อาจจะเพียงพอหากฉันสามารถหา ID กระบวนการของกระบวนการc(หรือb) ในแบบที่เชื่อถือได้ จากนั้นไพพ์ทั้งหมดสามารถเริ่มต้นแบบอะซิงโครนัสได้และฉันอาจรอรหัสกระบวนการ บางสิ่งบางอย่างตามแนวของ wait $(a | b | { c &amp; …
11 bash  shell  pipe  fifo 

2
ไปป์สำหรับเอาท์พุตป้องกันการแก้ไขตัวแปรท้องถิ่น
ฉันพยายามเขียนฟังก์ชั่นทุบตีง่ายๆที่ใช้เป็นอาร์กิวเมนต์จำนวนไฟล์และ / หรือไดเรกทอรี มันควรจะ: มีคุณสมบัติชื่อไฟล์อย่างเต็มที่ เรียงพวกเขา ลบรายการซ้ำ พิมพ์ทั้งหมดที่มีอยู่จริง ส่งคืนจำนวนไฟล์ที่ไม่มีอยู่ ฉันมีสคริปต์ที่เกือบจะทำในสิ่งที่ฉันต้องการ แต่ก็ล้มเหลวในการเรียงลำดับ ค่าส่งคืนของสคริปต์ตามที่ถูกต้อง แต่ผลลัพธ์ไม่ได้ (ไม่ได้เรียงลำดับและทำซ้ำ) ถ้าฉันบรรทัดเหล่า| sort -uคำสั่งตามที่ระบุเอาท์พุทที่ถูกต้อง 0แต่ค่าตอบแทนอยู่เสมอ ยินดีต้อนรับโซลูชัน NB ที่เรียบง่ายในการแก้ปัญหา แต่เป็นคำถามเกี่ยวกับสาเหตุที่เกิดขึ้นในรหัสที่ฉันมี นั่นคือเหตุใดการเพิ่มไพพ์จึงดูเหมือนว่าจะหยุดสคริปต์ที่เพิ่มค่าตัวแปรr? นี่คือสคริปต์: function uniqfile { local r=0 for arg in "$@" do readlink -e "$arg" || (( ++r )) done #| sort -u ## remove that comment return …

2
ฉันจะบอกได้อย่างไรว่าบัฟเฟอร์ของท่อเต็ม?
ฉันกำลังส่งออกท่อจากโปรแกรมหนึ่งไปยัง Perl บางอันที่ฉันเขียน นี่เป็นกระบวนการที่ใช้เวลานานบางครั้งหลายวันดังนั้นฉันต้องการค้นหาว่าคอขวดของฉันอยู่ที่ใดและพยายามเปิดมันขึ้นมา ฉันต้องการทราบว่าข้อมูลถูกส่งเข้าสู่สคริปต์ของฉันเร็วกว่าสคริปต์ของฉันหรือไม่ หากเป็นกรณีนี้ฉันจะพยายามปรับแต่งสคริปต์ของฉัน แต่ไม่ใช่ถ้าไม่ต้องการ ฉันเห็นการพูดคุยเกี่ยวกับการตั้งค่าสถานะเมื่อบัฟเฟอร์เต็มซึ่งป้องกันการเขียนอีกต่อไป แต่ฉันจะตรวจสอบเพื่อดูว่ามีการตั้งค่าสถานะหรือความถี่ได้อย่างไร? ความคิดใด ๆ
11 pipe 

2
ความแตกต่างของประสิทธิภาพระหว่าง stdin และอาร์กิวเมนต์บรรทัดคำสั่ง
สำหรับบางคำสั่งคุณสามารถระบุอินพุตบางตัวเป็น stdin หรืออาร์กิวเมนต์บรรทัดคำสั่ง โดยเฉพาะสมมติว่าcommandสามารถใช้การป้อนข้อมูล stdin และชื่อไฟล์เป็นอาร์กิวเมนต์บรรทัดคำสั่งและcommand &lt; myfile, cat myfile | command และcommand myfileสามารถผลิตผลเดียวกัน ตัวอย่างเช่น, เมื่อคำสั่งคือsed: sed s/day/night/ &lt;myfile &gt;new sed s/day/night/ myfile &gt;new cat myfile | sed s/day/night/ &gt;new เมื่อคำสั่งคือcat: cat &lt; myfile cat myfile ฉันสงสัยว่ามีกฎทั่วไปเกี่ยวกับการแสดงของพวกเขาหรือไม่นั่นคือหนึ่งในนั้นที่มักจะมีประสิทธิภาพมากที่สุดและอย่างน้อยที่สุด? การเปลี่ยนเส้นทางดีกว่าไปป์เสมอหรือไม่

1
zsh ไม่สามารถอินพุตไปยังเทอร์มินัลเมื่อวาง stdin และ stdout ด้วยคำสั่งตัวแปรที่มีเอาต์พุต tty
ข้อมูลระบบ: macOS Sierra 10.12.6 zsh 5.4.2 (x86_64-apple-darwin16.7.0) GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.3.0) เลื่อนไปที่ตัวอย่างที่ด้านล่างหากคุณเพียงต้องการขุดตัวอย่างง่าย ๆ ที่ฉันทำ หมายเหตุ: ฉันไม่ใช่zshผู้ใช้ที่ยิ่งใหญ่ ฉันกำลังมองหาfzfปุ่มลัดสำหรับbashและzsh. $(__fzfcmd)แจ้งให้ทราบว่าพวกเขาทั้งสองเรียกใช้คำสั่งตัวแปร __fzfcmdโดยเอาต์พุตดีฟอลต์fzfไปยัง stdout และการแทนที่พารามิเตอร์เพิ่งรัน command ( fzf) ซึ่งเป็นผลมาจากเอาต์พุต หนึ่งความแตกต่างระหว่างbashและzshสคริปต์เป็นที่bashหนึ่งต่อท่อส่งออกของ$(__fzfcmd)แต่zshเพียงแค่จับมันไว้ภายในอาร์เรย์ ฉันเดาว่าเป็นเพราะปัญหาzshเมื่อคุณไปป์ไลน์เอาท์พุทของfzfที่คุณไม่สามารถป้อนข้อมูลfzfและกระบวนการไพพ์ไปยังโดยfzfไม่ได้รับ stdin ใด ๆ ทางเลือกเดียวของคุณคือการหรือ^Z ดูเหมือนจะเป็นพื้นหลังกระบวนการด้วยเหตุผลบางอย่าง หรือบางทีพวกเขาแค่ต้องการแถวลำดับเพื่อที่จะได้วิ่งต่อไป รุ่นไม่มายากลบางอย่างในกุญแจสำคัญที่มีผลผูกพันกับ^C^Czle vi-fetch-historybash"\e^": history-expand-line ตอนนี้fzfไม่สำคัญ ดูเหมือนว่าคุณเพียงแค่ต้องใช้โปรแกรมที่ให้ผลลัพธ์ที่ttyจะเรียกโดยการทดแทนพารามิเตอร์เพื่อทำให้เกิดปัญหานี้ ดังนั้นฉันจะแสดงตัวอย่างที่ง่ายขึ้น ต่อไปนี้เป็นคำสั่งอื่น ๆ ที่ให้ผลลัพธ์ttyซึ่งอาจทำให้เกิดปัญหานี้ได้zsh: vipe (เรียกใช้เครื่องมือแก้ไขกลางท่อ) 'vim -' (ทำให้เป็นกลุ่มอ่านจาก stdin คล้ายกับ …
11 bash  zsh  pipe  tty 

4
รับ PID ของคำสั่งใด ๆ ในลำดับของ piped ของคำสั่ง
ถ้า, ในbash, ฉันเรียกใช้งาน: cmd1 | cmd2 | ... | cmdi | ... | cmdn &amp; ในกรณีที่cmd{1..n}ไม่ชัดเจนฉันจะได้รับ PID ได้cmdiอย่างไร อีกวิธีหนึ่งฉันจะส่งสัญญาณcmdiกระบวนการได้อย่างไร (ตัวอย่างเช่นส่งSIGUSR1?) pkill/ pgrep, pidofฯลฯ ดูไม่เหมือนคำตอบที่ดีเนื่องจากกรณีอื่น ๆcmdiอาจจะทำงานรวมทั้งเป็นส่วนหนึ่งของท่อเดียวกัน jobs -pให้ PID ของcmd1สำหรับฉัน i{1..n}สามารถเป็นอะไรก็ได้ใน
11 bash  shell  pipe  job-control 

3
การรับ PID ของคำสั่งก่อนหน้านี้ใน Pipeline
ฉันกำลังเขียนสคริปต์ทุบตีเพื่อใช้inotifywaitในการตรวจสอบไดเรกทอรีและเริ่มดำเนินการเมื่อตรวจพบการเปลี่ยนแปลง สิ่งที่ต้องการ: inotifywait -m ... | while read f; do something; done เนื่องจากinotifywaitไม่ได้ยุติลงเองสคริปต์นี้จะไม่หยุด ดังนั้นแผนของฉันคือรับ PID ของกระบวนการ inotifywait บันทึกลงในไฟล์และมีกระบวนการอื่นฆ่ามันในภายหลังเช่น: inotifywait -m ... | { echo ??PID?? &gt; pid-file; while ... } แต่ฉันไม่รู้วิธีรับ PID มีวิธีง่ายๆในการบรรลุเป้าหมายนี้หรือไม่? อีกวิธีหนึ่งก็คือการบันทึก PID ของเชลล์สคริปต์$$ไปยังไฟล์และฆ่าเชลล์สคริปต์ทั้งหมด แต่ฉันต้องการล้างข้อมูลบางอย่างหลังจากวนลูป ฉันลองใช้coprocแล้วฉันคิดว่ามันใช้งานได้ แต่ดูเหมือนว่าจะซับซ้อนกว่าที่จำเป็น
11 bash  pipe  pid 

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