Не удается fg функцию zsh, включая less.

Вопрос или проблема

У меня есть эта функция 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 работать корректно с интерактивным терминалом. Рассмотрим несколько подходов:

  1. Использование less в интерактивном режиме:
    Вы можете изменить функцию следующим образом:

    f() {
       /usr/bin/find . -type f | less
    }

    А затем перенаправить ввод-вывод:

    f() {
       ( /usr/bin/find . -type f | less )
    }
  2. Использование setsid:
    Этот подход позволяет изолировать обработку в отдельном сеансе:

    f() {
       setsid /usr/bin/find . -type f | less
    }

    Это гарантирует, что less будет иметь управление tty, и приостановка должна работать как ожидается.

  3. Использование nohup (не рекомендуется для данного случая):
    Можете попробовать использовать nohup, но это не всегда самый оптимальный метод, так как он может ограничить поведение вашего сеанса.

Заключение

Смена подхода с управлением терминалом или использование подстановочного процесса поможет вам устранить проблему с приостановкой и возобновлением функции, использующей less. Если ваши функции Zsh требуют обработки ввода-вывода в интерактивном режиме, не забудьте удостовериться, что они находятся в правильном контексте для работы с терминалом.

Если у вас возникнут дополнительные вопросы или нужна помощь с другими аспектами Zsh, не стесняйтесь обращаться за поддержкой.

Оцените материал
Добавить комментарий

Капча загружается...