How do I start a process in suspended state under Linux?

After starting a process, you can send it SIGSTOP to suspend it. To resume it, send SIGCONT. I think that this little script may help you

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

It runs process (command send as parameter), suspends it, prints process id and wait until it ends.


From which environment are you creating the process?

If you're doing it from an environment such as C code, you can fork() and then in the child, send a SIGSTOP to yourself before the exec(), preventing further execution.

A more generic solution (probably best) would be to create a stub that does so. So the stub program would:

  • Take arguments consisting of the real program's name and arguments
  • send a SIGSTOP to itself
  • exec() the real program with appropriate arguments

This will ensure that you avoid any sort of race conditions having to do with the new processing getting too far before you can send a signal to it.


An example for shell:

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

And using above code:

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

The jobs -l shows the PID. But if you're doing it from a shell you don't need the PID directly. You can just do: kill -CONT %1 (assuming you only have one job).

Doing it with more than one job? Left as an exercise for the reader :)


MikeyB's answer is correct. From this question on superuser, here's a more concise version:

( kill -SIGSTOP $BASHPID; exec my_command ) &

To understand this, one needs to understand how processes are started on unix: the exec system call replaces the currently running program with a new one, preserving the existing PID. So the way an independent process is created is to first fork, and then exec, replacing the running program in the child process with the desired program.

The ingredients of this shell command are:

  1. The parentheses (...) start a sub-shell: another instance of BASH.
  2. The kill command sends the STOP signal to this process, which puts it into the suspended state.
  3. As soon as you allow the process to continue (by sending it the CONT signal), the exec command causes it to replace itself with your desired program. my_command keeps the original PID of the sub-shell.
  4. You can use the $! variable to get the PID of the process.