Отключить процесс, который не был запущен из терминала
Я запускаю emacs из моего скрипта при входе в систему. Время от времени я случайно приостанавливаю его с помощью ctrl+z, и я не знаю, как с этим справиться.
Если бы я начал с терминала, jobs
а также fg
сделает свое дело, но в этом случае нет терминала для запуска.
Я вижу процесс запуска:
gauthier@sobel:~/data $ ps aux | grep emacs
gauthier 2932 0.0 0.6 565500 112540 ? Sl Apr14 0:11 emacs
gauthier 15189 0.0 0.0 11744 932 pts/2 S+ 15:54 0:00 grep --color=auto emacs
2 ответа
Emacs на самом деле не был приостановлен.
Как мы выяснили из-за устранения неполадок, emacs на самом деле не был приостановлен. Шоу приостановленных процессов T
как часть их состояния при просмотре через ps
тогда как в вашей ситуации emacs показал S
, что просто означает, что он ожидал события (в данном случае ожидал взаимодействия с пользователем).
Как объясняется в разделе "КОДЫ ГОСУДАРСТВЕННОГО ПРОЦЕССА" man ps
:
S interruptible sleep (waiting for an event to complete)
T stopped, either by a job control signal or because it is
being traced
Когда процесс приостанавливается, это считается сигналом управления заданием, поскольку приостановка процессов в основном выполняется как часть управления заданием (с &
в конце команды, Ctrl + Z, выданный в терминале, и jobs
встроенная оболочка). Увидеть ps
сама страница для документирования других кодов штатов, D
, R
, W
, X
, а также Z
,
Emacs был символизирован, а не приостановлен. Когда Ctrl + Z выдается процессу переднего плана в терминале, это приводит к приостановке процесса. Но вы нажали Ctrl + Z в окне emacs с графическим интерфейсом. Ctrl + Z не приостанавливает программы, если их использовать таким образом - например, во многих приложениях (таких как Firefox и LibreOffice) Ctrl + Z является нажатием клавиши для отмены.
Как вы могли подтвердить, при использовании emacs через графический интерфейс Ctrl + Z является комбинацией клавиш для того, чтобы сделать иконизацию (то есть минимизировать) окно или деиконифицировать (т.е. восстановить) его, если он уже иконизирован. Конечно, у вас должно быть выбрано иконизированное окно, чтобы де- иконизировать его с помощью Ctrl + Z, которое, по-видимому, ваш оконный менеджер может не поддерживать.
Обратите внимание, что когда вы нажимаете Ctrl + Z в окне терминала, маловероятно, что emacs сам перехватывает его и приостанавливает сам. Скорее всего, Ctrl + Z, выданный в терминале, обычно приостанавливает обработку, а Ctrl + Z, выданный в окне GUI, обычно нет.
Поскольку вы сказали, что вам "все еще интересно знать, как отключить процесс от терминала", и объяснение того, как узнать, действительно ли процесс приостановлен (и когда Ctrl + Z делает и не приостанавливает процесс), приводит к Разумное введение в ответ на этот вопрос я решил посвятить оставшейся части этого ответа рассмотрению этой части вопроса.
Возобновление приостановленных процессов с другого терминала
Если у вас есть доступ к управляющему терминалу приостановленной программы, jobs
, fg
, а также bg
Встроенные функции позволяют просматривать и возобновлять его. Если у вас нет доступа к управляющему терминалу программы, и все, что вам нужно сделать, это возобновить процесс, но не дать ему ввода или прочитать его вывод, на терминале, вы можете отправить процесс SIGCONT, как подробно описано в ответе zhongfu. Это, вероятно, то, что вы сделали бы, если бы графическая программа была приостановлена, и вы не могли возобновить ее с управляющего терминала. Это связано с тем, что основной способ взаимодействия с большинством приложений с графическим интерфейсом в большинстве случаев заключается в их графическом интерфейсе, а не в терминале.
Однако, если вам нужно отсоединить стандартные потоки процесса от его исходного терминала и подключить их к другому терминалу, то есть возобновить приостановленный процесс и взаимодействовать с ним в другом терминале, отличном от того, в котором он был запущен, - это не все так просто.
- В основном это понадобилось бы, если бы это была программа командной строки, предназначенная для взаимодействия с пользователем в основном через терминал, а не через какой-либо другой механизм, такой как GUI или локальный веб-сервер. Например, у вас гораздо больше шансов сделать это для
emacs -nw
чем для GUIemacs
,
Повторное подключение процесса к другому терминалу, если вы планировали заранее
Если вы ожидаете этого при запуске программы, вы можете полностью избежать этого, запустив процесс в терминальном мультиплексоре, а не в обычном терминале. screen
а также tmux
сделай это; увидеть man screen
а также man tmux
для деталей. ( См. Также byobu
,) Процесс начался в терминальном мультиплексоре, не подключенном напрямую к терминалу, через который вы взаимодействуете с ним, а вместо этого к псевдо-терминалу, предоставленному мультиплексором.
- Например, вы можете запустить
screen emacs
в одном терминале, а затем отсоедините его от этого терминала, нажав Ctrl + A, затем Ctrl + D и откройте его на другом терминале (или том же самом), запустивscreen -r
, Или, если вы никогда не отсоединяли его от первого терминала, вы отсоединяете его оттуда и подключаете к текущему терминалу с помощьюscreen -rd
,
Повторное подключение процесса к другому терминалу, если вы не планировали заранее
Если вы не запускали свою программу в терминальном мультиплексоре и вам необходимо отсоединить ее от исходного и подключить к новому, это обычно возможно, хотя и нетривиально с утилитами, установленными в Ubuntu по умолчанию. Это можно сделать, открыв и управляя процессом в отладчике.
К счастью, были написаны утилиты, с помощью которых это можно сделать легко - или, по крайней мере, попробовать легко. Я предлагаю reptyr. (См. Также injcode, neercs и сравнение трех на странице reptyr.) Файл readme Reptyr на странице github reptyr содержит информацию об использовании. В Ubuntu, чтобы загрузить и собрать reptyr, запустить его testsuite и установить его, вы можете использовать эти команды:
# Install build dependencies and set up /usr/local/src for administrators.
sudo apt-get update && sudo apt-get install build-essential git python-pip
pip install pexpect
cd /usr/local/src && sudo chgrp sudo . && sudo chmod g+w,+t .
# Retrieve, configure, build, test, and install reptyr.
git clone https://github.com/nelhage/reptyr.git && cd reptyr
make && sudo make test install
Вы можете заметить, что я делаю test
цель как корень с sudo. Как правило, рекомендуется создавать и тестировать программное обеспечение как обычный пользователь и повышать права пользователя до его установки. Однако в конфигурации Ubuntu по умолчанию reptyr не работает при запуске пользователем без полномочий root. Это связано с тем, что reptyr манипулирует дескрипторами файлов процесса, прикрепляя его к процессу как отладчик, но в качестве функции безопасности процессам без полномочий root запрещено отлаживать процессы, которые не являются их потомками.
Когда вы на самом деле используете reptyr
команда, вы не будете запускать его с sudo
, Вместо этого вы захотите запустить reptyr от имени того же пользователя, которому принадлежит процесс, из терминала, принадлежащего этому пользователю. (Возможно, есть способ заставить его работать без этого, но это работает только для меня.)
С помощью reptyr
на Ubuntu
Разрешение процессам отлаживать не-потомков, принадлежащих одному и тому же пользователю, может вызвать проблемы, только если запущенная программа успешно эксплуатируется (или если у вас есть вредоносное ПО). Один из способов разрешить работе reptyr, сохраняя при этом относительно низкий риск для безопасности, - разрешить его только тогда, когда вам нужно запустить reptyr - что, вероятно, является редким случаем - и впоследствии отключить его.
Итак, предположим, что вы запустили неграфический экземпляр Emacs (в недоступном терминале):
emacs -nw
Это может или не может быть приостановлено. Из другого терминала поменяй ptrace_scope
от 1 до 0, чтобы разрешить процессам отлаживать процессы, не являющиеся их потомками:
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
Тогда беги reptyr
передавая PID процесса в качестве аргумента, попытаться отсоединить его от старого терминала и подключить к новому:
reptyr PID
Вы можете найти PID в выводе ps x
или с pgrep
или же pidof
, Если есть только один emacs
работает, вы можете найти PID и передать его reptyr
в одной команде:
reptyr $(pidof emacs)
Я обнаружил, что это обычно работает, но иногда нет. Если reptyr
вообще не показывает вывод, возможно, вам придется нажать Ctrl + Z, чтобы использовать программу. (Я не знаю, почему это так, но работает ps
показывает, что ничто не приостанавливается или не приостанавливается, когда я нажимаю Ctrl + Z в этой конкретной ситуации, поэтому я подозреваю, что это связано с взаимодействием между reptyr и средствами управления заданиями моей оболочки.)
Управление заданиями может быть не полностью функциональным с подключенным процессом; например, вы не всегда можете приостановить его с помощью Ctrl + Z.
После того, как вы закончите с reptyr, вы можете установить ptrace_scope
Назад к 1 для безопасности:
echo 1 | sudo tee /proc/sys/kernel/yama/ptrace_scope
По возможности проще и надежнее планировать заранее. Если терминал, на котором вы запускаете интерактивную программу, может стать недоступным, лучше всего использовать терминальный мультиплексор, такой как screen
или же tmux
(как описано выше).
Вы можете запустить
kill -SIGCONT [pid]
или же
killall -SIGCONT [process name]
возобновить процесс [es] с указанным PID или именем процесса.