ว่าฉันมีมากเกินไปโปรแกรมa
และb
ที่ฉันสามารถทำงานด้วยและ./a
./b
เป็นไปได้หรือไม่ที่จะกระจายเอาท์พุทโดยไม่ต้องเขียนลงไฟล์ชั่วคราวก่อน?
ว่าฉันมีมากเกินไปโปรแกรมa
และb
ที่ฉันสามารถทำงานด้วยและ./a
./b
เป็นไปได้หรือไม่ที่จะกระจายเอาท์พุทโดยไม่ต้องเขียนลงไฟล์ชั่วคราวก่อน?
คำตอบ:
ใช้<(command)
เพื่อส่งเอาต์พุตของคำสั่งหนึ่งไปยังโปรแกรมอื่นราวกับว่าเป็นชื่อไฟล์ Bash ไพพ์เอาต์พุตของโปรแกรมไปยังไพพ์และส่งชื่อไฟล์/dev/fd/63
ไปยังคำสั่ง outer
diff <(./a) <(./b)
ในทำนองเดียวกันคุณสามารถใช้>(command)
ถ้าคุณต้องการสิ่งที่เป็นท่อในคำสั่ง
สิ่งนี้เรียกว่า "การทดแทนกระบวนการ" ในหน้า man ของ Bash
-bash: syntax error near unexpected token ('
และมีข้อผิดพลาดนี้: -bash: java: No such file or directory
ฉันพยายามอีกครั้งโดยไม่มีวงเล็บและได้ มันไม่ทำงานหากคำสั่งมีพารามิเตอร์หรือไม่
alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\'
ที่อัปลักษณ์ต่อไปนี้การทำงาน: (ตัวอย่างเช่น: diffcmd "ls" "ls -a")
fseek
ข้อเสนอ zsh =(./a)
ซึ่งสามารถใช้เหมือนกัน<(./a)
แต่ใช้ไฟล์ชั่วคราวภายใต้ประทุนซึ่ง zsh จะลบให้คุณ)
เพิ่มทั้งคำตอบถ้าคุณต้องการดูการเปรียบเทียบแบบเคียงข้างvimdiff
กันใช้:
vimdiff <(./a) <(./b)
บางสิ่งเช่นนี้
vimdiff
สร้างมุมมองการเปรียบเทียบความแตกต่างที่สวยงามสมาร์ทและการโต้ตอบ ดูเหมือนว่าจะมาพร้อมกับvim
แพ็คเกจในระบบส่วนใหญ่
vimdiff
ยังแสดงให้เห็นไม่เพียง แต่บรรทัดที่แตกต่าง แต่ยังรวมถึงส่วนข้อความเฉพาะที่แตกต่างกัน
ทางเลือกหนึ่งคือใช้ไปป์ที่มีชื่อ (FIFO) :
mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo
... แต่วิธีแก้ปัญหาของ John Kugelmanนั้นสะอาดกว่ามาก
rm a_fifo b_fifo
หลังจากที่ใช้พวกเขาด้วย
สำหรับทุกคนที่สงสัยนี่คือวิธีที่คุณทำการทดแทนกระบวนการในการใช้Fish shell :
ทุบตี:
diff <(./a) <(./b)
ปลา:
diff (./a | psub) (./b | psub)
แต่น่าเสียดายที่การดำเนินการในปลาปัจจุบันขาด ; ปลาจะแขวนหรือใช้ไฟล์ชั่วคราวบนดิสก์ คุณไม่สามารถใช้ psub สำหรับการส่งออกจากคำสั่งของคุณ
เพิ่มอีกเล็กน้อยเพื่อคำตอบที่ดีอยู่แล้ว (ช่วยฉัน!):
คำสั่งdocker
แสดงผลช่วยเหลือSTD_ERR
(เช่น file descriptor 2)
ฉันต้องการดูว่าdocker attach
และdocker attach --help
ให้ผลลัพธ์เดียวกัน
$ docker attach
$ docker attach --help
ฉันเพิ่งพิมพ์คำสั่งทั้งสองไปฉันก็ทำสิ่งต่อไปนี้:
$ diff <(!-2 2>&1) <(!! 2>&1)
!! เหมือนกับ! -1 ซึ่งหมายถึงเรียกใช้คำสั่ง 1 ก่อนหน้าคำสั่งนี้ - คำสั่งสุดท้าย
! -2 หมายถึงเรียกใช้คำสั่งสองก่อนหน้านี้
2> & 1 หมายถึงส่ง file_descriptor 2 เอาต์พุต (STD_ERR) ไปยังตำแหน่งเดียวกับ file_descriptor 1 เอาต์พุต (STD_OUT)
หวังว่านี้มีประโยชน์
สำหรับ zsh การใช้=(command)
จะสร้างไฟล์ชั่วคราวโดยอัตโนมัติและแทนที่=(command)
ด้วยพา ธ ของไฟล์เอง ด้วยการทดแทนกระบวนการปกติ$(command)
จะถูกแทนที่ด้วยเอาต์พุตของคำสั่ง
คุณสมบัติ zsh นี้มีประโยชน์มากและสามารถใช้เพื่อเปรียบเทียบผลลัพธ์ของสองคำสั่งโดยใช้เครื่องมือ diff เช่น Beyond Compare:
bcomp =(ulimit -Sa | sort) =(ulimit -Ha | sort)
สำหรับ Beyond Compare โปรดทราบว่าคุณต้องใช้bcomp
สำหรับด้านบน (แทนbcompare
) ตั้งแต่bcomp
เปิดตัวการเปรียบเทียบและรอให้เสร็จสมบูรณ์ หากคุณใช้ระบบจะเรียกใช้bcompare
การเปรียบเทียบและออกทันทีเนื่องจากไฟล์ชั่วคราวที่สร้างขึ้นเพื่อเก็บเอาต์พุตของคำสั่งหายไป
อ่านเพิ่มเติมได้ที่นี่: http://zsh.sourceforge.net/Intro/intro_7.html
โปรดสังเกตสิ่งนี้ด้วย:
โปรดทราบว่าเชลล์สร้างไฟล์ชั่วคราวและลบออกเมื่อคำสั่งเสร็จสิ้น
และต่อไปนี้ซึ่งเป็นความแตกต่างระหว่าง$(...)
และ=(...)
:
หากคุณอ่าน man page ของ zsh คุณอาจสังเกตเห็นว่า <(... ) เป็นอีกรูปแบบหนึ่งของการทดแทนกระบวนการซึ่งคล้ายกับ = (... ) มีความแตกต่างที่สำคัญระหว่างทั้งสอง ในกรณี <(... ), เชลล์สร้างไปป์ที่มีชื่อ (FIFO) แทนไฟล์ สิ่งนี้ดีกว่าเนื่องจากไม่ได้เติมระบบไฟล์ให้เต็ม แต่มันไม่ทำงานในทุกกรณี อันที่จริงแล้วถ้าเราแทนที่ = (... ) ด้วย <(... ) ในตัวอย่างด้านบนพวกเขาทั้งหมดจะหยุดทำงานยกเว้น fgrep -f <(... ) คุณไม่สามารถแก้ไขไปป์หรือเปิดเป็นโฟลเดอร์เมลได้ อย่างไรก็ตาม fgrep ไม่มีปัญหาในการอ่านรายการคำจากไปป์ คุณอาจสงสัยว่าเหตุใดแถบ diff <(foo) จึงไม่ทำงานเนื่องจาก foo | งานต่างบาร์ นี่เป็นเพราะ diff สร้างไฟล์ชั่วคราวหากสังเกตว่าข้อโต้แย้งข้อใดข้อหนึ่งของมันคือ - จากนั้นก็คัดลอกอินพุตมาตรฐานไปยังไฟล์ชั่วคราว