ข้อมูลระบบ:
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
^C
zle vi-fetch-history
bash
"\e^": history-expand-line
ตอนนี้fzf
ไม่สำคัญ ดูเหมือนว่าคุณเพียงแค่ต้องใช้โปรแกรมที่ให้ผลลัพธ์ที่tty
จะเรียกโดยการทดแทนพารามิเตอร์เพื่อทำให้เกิดปัญหานี้ ดังนั้นฉันจะแสดงตัวอย่างที่ง่ายขึ้น
ต่อไปนี้เป็นคำสั่งอื่น ๆ ที่ให้ผลลัพธ์tty
ซึ่งอาจทำให้เกิดปัญหานี้ได้zsh
:
- vipe (เรียกใช้เครื่องมือแก้ไขกลางท่อ)
'vim -'
(ทำให้เป็นกลุ่มอ่านจาก stdin คล้ายกับ vipe แต่จะไม่ส่งออกไปยัง stdout)
ในตัวอย่างด้านล่างแทนการเกิดขึ้นของทุกคนvipe
ด้วยvim -
ถ้าคุณไม่ต้องการที่จะทำแยกติดตั้ง เพียงจำไว้ว่าvim -
จะไม่ส่งออกเนื้อหาตัวแก้ไขไปยัง stdout เช่นvipe
นั้น
ตัวอย่าง:
1) echo 1 | vipe | cat # works in both bash and zsh
2) echo 1 | $(echo vipe) | cat # works in bash only. zsh problem with no output until I hit `^C`:
^C
zsh: done echo 1 |
zsh: suspended (tty output) $(echo vipe) |
zsh: interrupt cat
# seems like the process is backgrounded. I can still see it in jobs command
3) cat <(echo 1 | $(echo vipe)) # zsh and bash has the problem. I'm guessing because
# the file isn't finished writing and cat is
# blocking vipe's tty output
# both their `^C` output is just:
^C # nothing special, as expected
4) cat < <(echo 1 | $(echo vipe)) # works in both bash and zsh
5) echo 1 | $(echo vipe) > >(cat) # works in both bash and zsh
# The following don't have and input pipe to vipe.
# Type something then send EOF with ^D
6) vipe | cat # works for both
7) $(echo vipe) | cat # works for both
ตอนนี้ผมสงสัยว่าทำไมส่วนใหญ่2)
มีปัญหาสำหรับzsh
แต่ไม่bash
และทำไม4)
และแก้ไขปัญหาให้5)
zsh
ข้อกำหนดสำหรับzsh
การมีปัญหานี้ดูเหมือนจะเป็นสิ่งที่ฉันใส่ในชื่อ:
- ท่ออินพุต
- รันคำสั่งโดยการทดแทนตัวแปร / พารามิเตอร์ที่มี
tty
เอาต์พุต - ท่อส่งออก
UPDATE
ฉันได้เพิ่มวิธีแก้ไขอื่นที่ไม่ทำให้เกิดzsh
ปัญหานี้, 5)
. มันคล้ายกับ4)
แต่แทนที่จะเปลี่ยนเส้นทางstdout
โดยตรงไปยังstin
ฉันเปลี่ยนเส้นทางมันเป็นไฟล์ที่เปลี่ยนเส้นทางไปstdin
ใช้การทดแทนกระบวนการ
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
ps
จะบอกคุณในกรณีเหล่านี้ไม่มีเปลือกหอยที่แช่แข็งหรือติดอยู่ พวกเขากำลังรอกระบวนการของเด็กในวิธีปกติ และพวกเขาจะวนกลับไปที่พร้อมท์สำหรับการป้อนข้อมูลในวิธีปกติเมื่อกระบวนการลูกเหล่านั้นถูกระงับหรือยกเลิก ชื่อคำถามและเนื้อความของคุณรวมถึงหลักฐานเท็จโดยนัย "ทำไมเปลือกของฉันถึงแข็ง?" เป็นคำถามที่โหลดไม่ได้คำตอบเมื่อเปลือกของคุณไม่ได้แช่แข็งในตอนแรก คุณจะมีคำถามที่ดีกว่าสำหรับการลบหลักฐานเท็จโดยนัยนี้