Інформація про систему:
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за замовчуванням виводить fzfstdout, а підміна параметра просто виконує команду ( 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 -'(зробіть читати 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вихід - вихідна труба
ОНОВЛЕННЯ
Я додав ще один обхідний шлях , який не викликає , zshщоб мати цю проблему, 5). Це схоже на, 4)але замість того, щоб перенаправляти stdoutбезпосередньо в stin, я перенаправляю його у файл, який перенаправляє на stdinвикористання процесу заміни.
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
psвам підкаже висновок , ні в одному з цих випадків раковини не застигають і не застрягають. Вони просто чекають дитячих процесів у звичайному порядку; і вони дійсно повернуться до запиту на введення нормальним способом, як тільки ці дочірні процеси будуть призупинені або припинені. Назва та тіло питання містять неявну помилкову передумову. "Чому моя оболонка замерзає?" - це невідповідне завантажене питання, коли ваша оболонка фактично не замерзає. У вас буде краще питання про видалення цієї неявної помилкової передумови.