Reputation: 1352
I have a really huge archive, which must be extracted file by file and further processed. I don't have enough memory to extract the whole archive (neither in RAM nor on the flash) - thus I wrote a small application which stops (raise(SIGSTOP)
) after each extracted file. An equivalent could be this code:
#include <stdio.h>
#include <signal.h>
int main() {
printf("started.\n"); fflush(stdout);
sleep(2); // extracting archive
printf("stopping\n"); fflush(stdout);
raise(SIGSTOP); // stopping
printf("resume + done\n"); fflush(stdout);
return 0;
}
This works fine while I execute this in the terminal:
$ gcc -o dosleep main.c
$ ./dosleep
started.
stopping
[1]+ Stopped ./dosleep
$ fg
./dosleep
resume + done
$
But when calling the method from a script, the command never returns:
$ cat doit.sh
#!/bin/sh
echo "STARTING"
./dosleep
echo "BACK"
$ ./doit.sh
STARTING
started.
stopping
^C^C^C^C^C^C
Why do terminal and script behave so differently? Is there a way to change this behavior?
Thanks, Karl
Upvotes: 1
Views: 293
Reputation: 295629
Job control is off-by-default in noninteractive shells, but you can enable it explicitly:
set -m
Thus, if we modify your script to add either the set -m
line or a -m
on the shebang as follows:
#!/bin/bash -m
./start-delay
echo BACK
...then BACK
is emitted after stopping
.
Quoting from the bash man page section on set
, emphasis added:
-m
Monitor mode. Job control is enabled. This option is on by default for interactive shells on systems that support it (see JOB CONTROL above). All processes run in a separate process group. When a background job completes, the shell prints a line containing its exit status.
Upvotes: 2