Practically, I need a process which behaves, as if I had pressed Ctrl+Z just after it started.

Hopefully, it is possible to do such thing using a shell script.

(Also, knowing the resulting PID would be great, so I could continue the process afterwards.)

link|improve this question

feedback

2 Answers

up vote 3 down vote accepted

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.

link|improve this answer
I modified it to continue at the end: [enter] #!/bin/bash [enter] $@ & [enter] PID=$! [enter] kill -STOP $PID [enter] echo "Suspended: $PID, press ENTER to continue it" [enter] read [enter] kill -CONT $PID [enter] wait $PID [enter] echo – java.is.for.desktop Jul 25 '11 at 5:35
Just so you know, the subprocess may finish before you even get a chance to send the STOP signal to it. – MikeyB Jul 25 '11 at 13:06
feedback

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 codez:

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 :)

link|improve this answer
I was hoping to do this from a shell script... – java.is.for.desktop Jul 24 '11 at 23:32
Great, so since you want to do this from a shell script, use the stub program. – MikeyB Jul 25 '11 at 2:46
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.