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

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

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

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

3 ответа

Решение

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

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

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

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

Если вы делаете это из среды, такой как код на 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 процесса.
Другие вопросы по тегам