Як призупинити та вивести фоновий процес на перший план


166

У мене процес, який спочатку тривав на першому плані. Я призупинив значення Ctrl+ Z, а потім відновив його роботу у фоновому режимі на bg <jobid>.

Цікаво, як призупинити процес, що працює у фоновому режимі?

Як я можу вивести фоновий процес на перший план?

Редагувати:

Процес виводить на stderr, тож як я можу видавати команду, fg <jobid>коли процес виводиться на термінал?


1
Ви все одно можете вводити команди в терміналі, який видає помилки. Текст, набраний на STDERR, не вважається вхідним, лише клавіші, які ви надсилаєте. На екрані це виглядає заплутано, але це працює.
Калеб

@Caleb: Навіть коли процес виводиться на stdout, я все одно можу набрати, fg <jobid>щоб зробити його переднім планом?
Тім

@Tim: Так, можна.
Калеб

Відповіді:


214

Як сказав Тім, введіть, fgщоб повернути останній процес на перший план.

Якщо у вас у фоновому режимі працює більше одного процесу, зробіть це:

$ jobs
[1]   Stopped                 vim
[2]-  Stopped                 bash
[3]+  Stopped                 vim 23

fg %3щоб повернути vim 23процес на перший план.

Щоб призупинити процес запуску у фоновому режимі, використовуйте:

kill -STOP %job_id

Сигнал SIGSTOP зупиняє (призупиняє) процес по суті так само Ctrl+ Zробить.

Приклад: kill -STOP %3.

джерела: Як надсилати сигнали процесам в Linux та Unix та як керувати фоновими та передніми роботами .


23
сигнал 19 - це SIGCONTдля мене; Я використовую kill -STOPі віддаю kill -CONTперевагу запам'ятовувати цифри в будь-якому випадку, але ви можете перевірити, kill -lщоб нагадати про числові значення
Марно

Процес виводить на stderr, тож як я можу видавати команду jobі fg <jobid>поки процес виводиться на термінал?
Тім

1
@Tim Просто введіть команду, як зазвичай. Поки робота не працює в фоновому режимі, вона не читає те, що ви вводите - ваша оболонка. Те, що ви вводите, може здатися вам розбитим, але оболонка зрозуміє це просто чудово.
AlexWebr

@AlexWebr: Дякую, це працює! (1) Чи фонове завдання не приймає жодного вводу та виводу, включаючи "Ctrl + Z" тощо, так? (2) Чи можна безпосередньо призупинити роботу, що працює у фоновому режимі? Якщо так, то як? Якщо ні, чи потрібно її спочатку змінити для запуску на передньому плані, перш ніж її можна призупинити?
Тім

2
Чи можна роботу, що працює у фоновому режимі, безпосередньо призупинено так: kill -STOP %job_idяк пояснено
Марно

31

Це має стосуватися будь-якої оболонки з контролем роботи, яку (здебільшого) ви можете прийняти як належне, якщо не мати справу з справді древньою оболонкою. Це в стандарті POSIX , тому навіть dashпідтримує контроль за роботою (при інтерактивному запуску або з ним -m).

Інтерактивний

  • Ctrl+ zпризупинить програму, що наразі планується
  • bgбуде фоном останньої призупиненої програми
    (використовувати bg %2номер завдання, який ви можете перевірити jobs)
  • fg вийде на перший план останню призупинену програму

В zsh, ви можете написати зв'язування з неявно запустити ключ fgз командного рядка з допомогою іншого Ctrl+ z:

_zsh_cli_fg() { fg; }
zle -N _zsh_cli_fg
bindkey '^Z' _zsh_cli_fg

Напевно, є також розумний спосіб неявно втекти bgпризупинення, але це здається нерозумним; принаймні для мене, більшість моїх Ctrl+ zвикористання відбувається тому , що Ctrl+ cне вдається вирватися; Я хочу слідувати за цим, наприклад, kill %1а не bg, і я, звичайно, не хочу замовчувати вбивство! (Ця логіка також поширюється на те, чому я більше не використовую цю прив'язку клавіш. Якщо я забиваю Ctrl+, zщоб зупинити процес, останнє, що я хочу зробити, - це відновити!)

Неінтерактивний

Якщо ви перебуваєте в іншому екземплярі оболонки (або інший користувач, іноді включаючи sudoкоманди), ви, ймовірно, не зможете використовувати номери завдань.

Ви все ще можете діяти на іншому процесі, коли дізнаєтесь його ідентифікатор процесу (PID). Ви можете отримати PID за допомогою pgrep …або ps aux |grep …(або з тієї ж оболонки jobs -l, або $!), а потім можете запустити:

kill -STOP $PID  # suspend
kill -CONT $PID  # continue (resume)

Якщо ви не знаєте ідентифікатора процесу і не переживаєте про призупинення інших примірників процесу за назвою, ви можете передавати сигнали одному з таких:

killall -STOP program_name
pkill -STOP program_name
pkill -f -STOP program_name_or_args

CONTСигнал до програми зупиняли Ctrl+ z(а не bg«г) відновить прогрес (на передньому плані), те ж саме , як якщо б ви були fgйого.

Re: Стандартна помилка

Редагування цього питання задає стандартну помилку:

Процес виводить на stderr, тож як я можу видавати команду, fg <jobid>коли процес виводиться на термінал?

Якщо у заданій роботі немає фонових компонентів (або все завдання фонове, можливо, через kill -CONT), ви фактично не бачите вихід, поки він призупинено.

Якщо він все ще виводить дані (будь то стандартний вихід або стандартна помилка), це, безумовно, зробить ваш термінал візуально захаращеним, але весь цей вихід буде ігнорований, оскільки він не є частиною вашого вводу. Це може ускладнити усвідомлення того, що ви не ввели жодних помилок, але (сліпо) набору тексту fgEnterмає бути достатньо (якщо у вас є кілька завдань, і те, про що йдеться, не є останнім, і в цьому випадку вам справді потрібен дескриптор роботи ).

Якщо вам потрібно знайти дескриптор завдання, скористайтеся іншим терміналом, щоб надіслати йому STOPсигнал за допомогою неінтерактивних методів, описаних вище. Це має звільнити ваш дисплей (можливо, натисніть Enterкілька разів або запустіть clearабо Ctrl+ L), щоб потім можна запустити, jobsщоб знайти дескриптор завдання, а потім запустити, fg %Nде Nце число.


Єдина проблема призупинення та відновлення процесів полягає в тому, що якщо ви зробили якісь з'єднання з якоюсь іншою програмою (наприклад, RabbitMQ), під час відновлення з'єднання буде втрачено.
Nav

@Nav - Це тому, що ти його не запустив без голови. В bash і zsh, я вважаю, що вам просто потрібно відмовитись від фонового процесу. Я вважаю за краще виконувати такі завдання з nohup або термінальним мультиплексором, як екран або tmux . Ви не можете підібрати процес nohup (так само як ви не можете відновити фоновий процес із окремого з'єднання), але ви можете підключитися до мультиплексора.
Адам Кац

Це був фоновий процес. Я закрив термінал, а потім увійшов на сервер з іншого терміналу.
Nav

Так, ви не можете відновити процес з іншої оболонки, якщо він не був запущений з урахуванням цього. Я рекомендую екран або tmux для цього.
Адам Кац

Я вважаю, що якщо ви надішлете CONTсигнал процесу (роботі / конвеєру), зупиненому Ctrl + Z, він відновиться у фоновому режимі, навіть якщо ви цього не зробили bg.
G-Man

10

Введіть fgйого на перший план.


Дякую! Процес виводить на stderr, тож як я можу видавати команду, fg <jobid>коли процес виводиться на термінал?
Тім

1
  1. список завдань з jobsкомандою
  2. Виведіть свою цільову роботу на перший план за допомогою fg; наприклад: fg %4
  3. Натисніть, CTRL Zщоб призупинити
  4. Щоб почати його працювати у фоновому режимі, використовуйте bg; наприклад:bg %4

0

Закінчити процес можна декількома різними способами. Часто із команди, що базується на консолі, відправлення Ctrlcнатискання клавіші (символу переривання за замовчуванням) буде виходити з команди. Це працює, коли процес працює в передньому плані.

Якщо процес працює у фоновому режимі, то спочатку вам потрібно буде отримати його ідентифікатор роботи за допомогою psкоманди, а після цього ви можете скористатися командою kill, щоб вбити процес таким чином:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated

Тут killкоманда припинить first_oneпроцес. Якщо процес ігнорує звичайну killкоманду, ви можете використовувати kill -9наступний ідентифікатор процесу:

$kill -9 6738
Terminated

1
Хоча це правда, він не відповідає на питання ...
jasonwryan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.