Как сделать Ctrl-Z и bg одним нажатием клавиши, чтобы процесс продолжался в фоновом режиме?


25

Я следую этой схеме приостановки задачи, а затем позволяю ей продолжаться слишком часто в Ctrl-Z bgпоследовательности.

Мне было интересно, есть ли способ сжать это до одного нажатия клавиши?

Моя оболочка zsh


Я хочу сказать, что это, вероятно, жестко закодировано. Но я не на 100%
Чад Харрисон

Конечно, но я нашел элегантное решение, спасибо superuser.com/a/161922/35223
Евгений Долженко

Ответы:


24

Последовательность Ctrl+ Zобрабатывается терминалом, а не оболочкой. (Полезный фон: какова точная разница между терминалом, оболочкой, tty и консолью? )

Только небольшой нерасширяемый набор функций может быть связан с ключом в терминале . Вы можете настроить ключи, привязанные к этим функциям, но не добавлять другую функцию. Эти функции делятся на три категории:

  • Редакция командной строки в программах, которые не предоставляют свои собственные (канонический режим, также называемый режимом приготовления (в отличие от режима raw), который вы редко будете использовать на практике): конец файла ( eof, Ctrl+ D), конец строки ( eol, Ctrl+ M), удалить символ слева ( erase, Ctrl+ H), удалить слово слева ( werase, Ctrl+ W), удалить строку ( kill, Ctrl+ U).
  • Ручное управление потоком: stop( Ctrl+ S), start( Ctrl+ Q). Полезно только на старых последовательных терминалах, которые пропускали символы, когда терминал не мог угнаться за компьютером или наоборот.
  • Сигнализация: прерывание ( intr, Ctrl+ C), принудительное завершение ( quit, Ctrl+ \), приостановка ( Ctrl+ Z).

Некоторые системы, в том числе Linux, расширяют этот список, но я никогда не видел ни одной, включающей фоновую обработку. Обратите внимание, что он будет поддерживаться как в драйвере терминала в ядре, так и в эмуляторе терминала. Таким образом, вы должны обойтись с suspend, который отправляет на передний план сигнал SIGTSTP . Это запускает SIGCHLD в родительском процессе лидера приоритетного задания, которым обычно является оболочка. Когда оболочка получила SIGCHLD, она звонит, waitpidчтобы выяснить, почему она была уведомлена, и, обнаружив, что фоновое задание было приостановлено, отображает уведомление (например [1] + 12345 suspended mycommand) и новое приглашение.

Вы можете запрограммировать оболочку для отправки SIGCONTсигнала на задание переднего плана. Я не думаю, что у zsh есть ловушка для этого, вам нужно будет исправить исходный код. И у zsh нет никакого способа узнать, действительно ли вы хотели прервать программу (упс, эта программа может делать что-то не то, позвольте мне приостановить ее, пока я разбираюсь) или справиться с ней.


Что я делаю, это чтобы установить Ctrl+Z задаю последовательность клавиш в zsh для фонового изображения текущего задания ( %%). Таким образом, я могу отправить задний план на задний план, нажав Ctrl+ Z Ctrl+ Z. Пока я в этом, я заставляю Ctrl+ Zделать что-то еще полезное, когда текущая строка ввода не пуста (поэтому я не просто вернулся из подпроцесса): «приостановить» текущую строку ввода, что позволяет мне набрать другую команду после чего прерванная строка помещается обратно во входной буфер.

fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z

Жиль, это невероятно полный, обучающий и вдумчивый ответ, которого я не мог ожидать! Спасибо большое!
Евгений Долженко

2

^ z ^ z, как zsh выше, возможно в bash, хотя это немного глупо, и я долго не запускал это:

  • В ваш .inputrc включите отображение "\C-z": "bg\n"
  • В переменную bash PS0 входит `$ (stty susp ^ z) '
  • В переменную bash PROMPT_COMMAND входит 'stty susp ^ @'

поэтому ^ z для приостановки включается при запуске команды, а затем отключается для приглашения bash.


1

Так что нашел решение, не совсем то, что я хочу, но чертовски близко отсюда /superuser//a/161922/35223

В пустой командной строке запускается bg (так что Ctrl + Z Ctrl + Z приостанавливает работу программы и немедленно возобновляет ее в фоновом режиме).


Замечу, что для этого требуется zsh; это не поддерживается в bash. (во всяком случае, из коробки)
Кевин М.

@KevinM Вы можете написать аналогичную функцию в bash (по крайней мере, для базовой версии, Ctrl+Zвызывающей bg, я не уверен в обнаружении непустой строки ввода).
Жиль "ТАК - перестань быть злым"

0

Являются ли эти команды, которые вы хотели сначала выполнить на переднем плане, а затем переключиться на фон? Я не знаю, есть ли более простой способ сделать это. Но если вы хотите запустить команды, которые будут в фоновом режиме, вы можете просто добавить амперсанд в конец строки. например, ping google.com &начнется пинг в фоновом режиме; вы не сможете взаимодействовать с ним, если не наберете fg.


1
Спасибо, проблема в том, что иногда вы не представляете, сколько времени займет выполнение команды, поэтому вы работаете в интерактивном режиме, а затем понимаете, что вам лучше позволить продолжить работу в фоновом режиме. Принятый ответ творит чудеса для меня, используя его ежедневно!
Евгений Долженко

Спасибо за ответ. Принятый ответ довольно опрятен!
Октябрь
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.