Como inicio um processo em estado suspenso no Linux?

17

Praticamente, preciso de um processo que se comporte como se eu tivesse pressionado Ctrl+Z logo depois de começar.

Espero que seja possível fazer isso usando um script de shell.

(Além disso, saber o PID resultante seria ótimo, então eu poderia continuar o processo depois).

    
por java.is.for.desktop 25.07.2011 / 00:15

3 respostas

8

Depois de iniciar um processo, você pode enviar SIGSTOP para suspendê-lo. Para retomar, envie SIGCONT. Eu acho que esse pequeno roteiro pode te ajudar

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

Executa process (comando send as parameter), suspende, imprime o id do processo e aguarda o término.

    
por 25.07.2011 / 03:17
19

De qual ambiente você está criando o processo?

Se você estiver fazendo isso de um ambiente como o código C, você pode fork () e, em seguida, no filho, enviar um SIGSTOP para si mesmo antes do exec (), evitando a execução posterior.

Uma solução mais genérica (provavelmente melhor) seria criar um stub que o faça. Então o programa stub iria:

  • Aceite argumentos que consistam no nome e nos argumentos do programa real
  • envia um SIGSTOP para si mesmo
  • exec () o programa real com argumentos apropriados

Isso garantirá que você evite qualquer tipo de condição de corrida relacionada ao novo processamento que esteja muito longe antes de poder enviar um sinal para ele.

Um exemplo para o shell:

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

E usando o codez acima:

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:~$ 

O jobs -l mostra o PID. Mas se você estiver fazendo isso a partir de um shell, não precisará do PID diretamente. Você pode fazer apenas: kill -CONT %1 (supondo que você tenha apenas um emprego).

Fazendo isso com mais de um emprego? Deixado como um exercício para o leitor:)

    
por 25.07.2011 / 00:32
15

A resposta de MikeyB está correta. De esta pergunta no superusuário, aqui está uma versão mais concisa:

( kill -SIGSTOP $BASHPID; exec my_command ) &

Para entender isso, é necessário entender como os processos são iniciados no unix: a chamada do sistema exec substitui o programa atualmente em execução por um novo , preservando o PID existente. Portanto, a maneira como um processo independente é criado é primeiro fork e, em seguida, exec , substituindo o programa em execução no processo filho pelo programa desejado.

Os ingredientes deste comando shell são:

  1. Os parênteses (...) iniciam um sub-shell: outra instância de BASH.
  2. O comando kill envia o sinal STOP para esse processo, que o coloca no estado suspenso.
  3. Assim que você permitir que o processo continue (enviando o sinal CONT ), o comando exec faz com que ele substitua a si mesmo pelo programa desejado. my_command mantém o PID original da sub-casca.
  4. Você pode usar a variável $! para obter o PID do processo.
por 07.10.2012 / 21:13