Вопрос или проблема
У меня есть эта функция zsh:
f() {
/usr/bin/find . -type f | less
}
Когда я вызываю эту функцию, приостанавливаю её с помощью Ctrl+z, а затем выполняю fg, отображается zsh: suspended (tty output) /usr/bin/find . -type f |
, и я не могу возобновить выполнение. Почему это происходит? Как я могу возобновить выполнение?
arch% f
zsh: suspended /usr/bin/find . -type f |
arch% fg
[2] - continued /usr/bin/find . -type f |
zsh: suspended (tty output) /usr/bin/find . -type f |
zsh: suspended (tty output) /usr/bin/find . -type f |
arch%
Если я запускаю /usr/bin/find . -type f | less
напрямую из командной строки, не делая это функцией, она приостанавливается и возобновляется нормально.
Ответ или решение
Ваша проблема с функцией Zsh, которая использует less
и срабатывает при нажатии Ctrl+Z, связана с поведением объединения процессов и управления терминалом в командной оболочке. Давайте подробно разберёмся в этой ситуации и выясним, как её исправить.
Проблема
При выполнении вашей функции f
, она запускает команду find
, результаты которой передаются в less
. Когда вы приостанавливаете выполнение функции с помощью Ctrl+Z, это приводит к тому, что find
и less
оказываются в состоянии ожидания, ожидая ввода терминала. Однако, когда вы пытаетесь возобновить работу с помощью команды fg
, Zsh сообщает, что она "подвешена (tty output)", из-за того что less
требует интерактивного tty для корректного отображения данных.
Почему это происходит?
Когда вы вызываете:
/usr/bin/find . -type f | less
в интерактивном режиме, оболочка правильно настраивает управление процессами, и, когда less
активен, он ожидает ввода от терминала. Ваша функция f
, однако, не устанавливает должным образом управление tty, что приводит к образованию "потерянного" состояния для процесса less
.
Решение
Чтобы функция работала корректно, вы можете использовать оператор подстановки для создания нового сеанса с помощью команд setsid
, или вы можете изменить функцию, чтобы позволить less
работать корректно с интерактивным терминалом. Рассмотрим несколько подходов:
-
Использование
less
в интерактивном режиме:
Вы можете изменить функцию следующим образом:f() { /usr/bin/find . -type f | less }
А затем перенаправить ввод-вывод:
f() { ( /usr/bin/find . -type f | less ) }
-
Использование
setsid
:
Этот подход позволяет изолировать обработку в отдельном сеансе:f() { setsid /usr/bin/find . -type f | less }
Это гарантирует, что
less
будет иметь управление tty, и приостановка должна работать как ожидается. -
Использование
nohup
(не рекомендуется для данного случая):
Можете попробовать использоватьnohup
, но это не всегда самый оптимальный метод, так как он может ограничить поведение вашего сеанса.
Заключение
Смена подхода с управлением терминалом или использование подстановочного процесса поможет вам устранить проблему с приостановкой и возобновлением функции, использующей less
. Если ваши функции Zsh требуют обработки ввода-вывода в интерактивном режиме, не забудьте удостовериться, что они находятся в правильном контексте для работы с терминалом.
Если у вас возникнут дополнительные вопросы или нужна помощь с другими аспектами Zsh, не стесняйтесь обращаться за поддержкой.