Інформація про систему:
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, а підміна параметра просто виконує команду ( 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
вам підкаже висновок , ні в одному з цих випадків раковини не застигають і не застрягають. Вони просто чекають дитячих процесів у звичайному порядку; і вони дійсно повернуться до запиту на введення нормальним способом, як тільки ці дочірні процеси будуть призупинені або припинені. Назва та тіло питання містять неявну помилкову передумову. "Чому моя оболонка замерзає?" - це невідповідне завантажене питання, коли ваша оболонка фактично не замерзає. У вас буде краще питання про видалення цієї неявної помилкової передумови.