Назад | Перейти на главную страницу

Как запустить процесс в приостановленном состоянии под Linux?

Практически мне нужен процесс, который ведет себя так, как если бы я нажал Ctrl+Z сразу после того, как это началось.

Надеюсь, это возможно сделать с помощью сценария оболочки.

(Кроме того, было бы здорово знать, что полученный PID, чтобы я мог продолжить процесс позже.)

В какой среде вы создаете процесс?

Если вы делаете это из среды, такой как код C, вы можете fork (), а затем в дочернем элементе отправить себе сигнал SIGSTOP перед exec (), предотвращая дальнейшее выполнение.

Более общим решением (возможно, лучшим) было бы создание заглушки, которая делает это. Таким образом, программа-заглушка:

  • Возьмите аргументы, состоящие из реального имени программы и аргументов
  • отправить SIGSTOP самому себе
  • exec () реальная программа с соответствующими аргументами

Это гарантирует, что вы избежите каких-либо состояний гонки, связанных с тем, что новая обработка заходит слишком далеко, прежде чем вы сможете отправить ей сигнал.


Пример для оболочки:

#!/bin/bash
kill -STOP $$
exec "$@"

И используя код выше:

michael@challenger:~$ ./stopcall.sh ls -al stopcall.sh

[1]+  Stopped                 ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ jobs -l
[1]+ 23143 Stopped (signal)        ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ kill -CONT 23143; sleep 1
-rwxr-xr-x 1 michael users 36 2011-07-24 22:48 stopcall.sh
[1]+  Done                    ./stopcall.sh ls -al stopcall.sh
michael@challenger:~$ 

В jobs -l показывает PID. Но если вы делаете это из оболочки, вам не нужен PID напрямую. Вы можете просто сделать: kill -CONT %1 (при условии, что у вас только одна работа).

Делаете это с более чем одной работой? Оставил в качестве упражнения для читателя :)

Ответ MikeyB правильный. Из этот вопрос на суперпользователе, вот более краткая версия:

( kill -SIGSTOP $BASHPID; exec my_command ) &

Чтобы понять это, нужно понять, как процессы запускаются в unix: exec системный вызов заменяет запущенную в данный момент программу на новую, сохраняя существующий PID. Таким образом, независимый процесс создается следующим образом: fork, а потом exec, заменяя запущенную программу в дочернем процессе нужной программой.

Ингредиенты этой команды оболочки:

  1. Круглые скобки (...) запустить суб-оболочку: еще один экземпляр BASH.
  2. В kill Команда отправляет этому процессу сигнал STOP, который переводит его в состояние ожидания.
  3. Как только вы разрешите процессу продолжить (отправив ему CONT сигнал), exec команда заставляет его заменить себя с желаемой программой. my_command сохраняет исходный PID суб-оболочки.
  4. Вы можете использовать $! переменная, чтобы получить PID процесса.

После запуска процесса вы можете отправить ему сигнал SIGSTOP, чтобы приостановить его. Чтобы возобновить его, отправьте SIGCONT. Я думаю, что этот небольшой сценарий может вам помочь

#!/bin/bash
$@ &
PID=$!
kill -STOP $PID
echo $PID
wait $PID

Он запускает процесс (команда отправляется как параметр), приостанавливает его, печатает идентификатор процесса и ждет его завершения.