Thông tin hệ thống:
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)
Di chuyển đến VÍ TRÍ ở phía dưới nếu bạn chỉ muốn tìm hiểu các ví dụ đơn giản mà tôi đã thực hiện.
LƯU Ý: Tôi không phải là zshngười dùng lớn .
Tôi đã nhìn vào các fzfkeybindings cho bashvà zsh.
Lưu ý cách cả hai chạy một lệnh biến $(__fzfcmd). __fzfcmdtheo mặc định đầu ra fzfcho thiết bị xuất chuẩn và thay thế tham số chỉ chạy lệnh ( fzf) kết quả từ đầu ra.
Một điểm khác biệt giữa tập lệnh bashvà zshtập lệnh là bashcái tiếp tục dẫn đầu ra của đầu ra $(__fzfcmd)nhưng zshchỉ bắt nó bên trong một mảng. Tôi đoán là do có vấn đề zshkhi bạn tiếp tục dẫn đầu ra của fzfnơi bạn không thể nhập vào fzfvà quá trình được dẫn đến bởi fzfkhông nhận được bất kỳ stdin nào. Sự lựa chọn duy nhất của bạn là ^Zhoặc ^C. ^Cdường như để làm nền cho quá trình này Hoặc có lẽ họ chỉ muốn nó trong một mảng để họ có thể chạy zle vi-fetch-historytrên nó . Các bashphiên bản hiện một số phép thuật trong khóa ràng buộc với"\e^": history-expand-line
Bây giờ fzfkhông quan trọng. Có vẻ như bạn chỉ cần một chương trình xuất ra ttyđể được gọi bằng cách thay thế tham số để gây ra vấn đề này. Vì vậy, tôi sẽ chỉ ra một số ví dụ đơn giản hơn.
Dưới đây là một số lệnh khác xuất ra ttycó thể gây ra sự cố này trong zsh:
- vipe (chạy trình soạn thảo ở giữa một đường ống)
'vim -'(làm cho vim đọc từ stdin. tương tự như vipe nhưng sẽ không xuất ra stdout)
Trong các ví dụ dưới đây, thay thế mọi lần xuất hiện vipebằng vim -nếu bạn không muốn thực hiện cài đặt riêng. Chỉ cần nhớ rằng vim -sẽ không xuất nội dung trình soạn thảo ra thiết bị xuất chuẩn như thế vipenào.
VÍ DỤ:
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
Bây giờ, tôi chủ yếu tự hỏi tại sao 2)có một vấn đề cho zshnhưng không phải cho bashvà tại sao 4)và 5)khắc phục vấn đề cho zsh.
Các yêu cầu zshđể có vấn đề này dường như chính xác là những gì tôi đặt trong tiêu đề:
- ống đầu vào
- lệnh chạy bằng thay thế biến / tham số có
ttyđầu ra - ống đầu ra
CẬP NHẬT
Tôi đã thêm một cách giải quyết khác mà không gây ra zshvấn đề này 5). Nó tương tự 4)nhưng thay vì chuyển hướng stdouttrực tiếp vào stin, tôi chuyển hướng nó thành một tệp chuyển hướng stdinsử dụng thay thế quy trình.
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
pssẽ cho bạn biết, không có trường hợp nào trong số này là vỏ bị đóng băng hoặc bị kẹt. Họ chỉ đơn giản là chờ đợi các quá trình con theo cách thông thường; và họ thực sự sẽ lặp lại để nhắc nhở đầu vào theo cách thông thường một khi các quá trình con đó bị đình chỉ hoặc chấm dứt. Tiêu đề và cơ thể câu hỏi của bạn bao gồm một tiền đề sai ngầm định. "Tại sao vỏ của tôi đóng băng?" là một câu hỏi được tải không thể trả lời khi vỏ của bạn không thực sự đóng băng ở nơi đầu tiên. Bạn sẽ có một câu hỏi tốt hơn để loại bỏ tiền đề sai lầm ngầm này.