2017-12-18 3 views
0

Ich habe ein wirklich großes Archiv, das Datei für Datei extrahiert und weiterverarbeitet werden muss. Ich habe nicht genügend Speicher, um das gesamte Archiv zu extrahieren (weder im RAM noch auf dem Flash) - also habe ich eine kleine Anwendung geschrieben, die nach jeder extrahierten Datei stoppt (raise(SIGSTOP)). Ein Äquivalent könnte dieser Code sein:SIGSTOP funktioniert nicht, wenn Skript

#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; 
} 

Dies funktioniert gut, während ich dies im Terminal ausführen:

$ gcc -o dosleep main.c 
$ ./dosleep 
started. 
stopping 

[1]+ Stopped     ./dosleep 
$ fg 
./dosleep 
resume + done 
$ 

Aber wenn das Verfahren aus einem Skript aufrufen, gibt der Befehl nie:

$ cat doit.sh 
#!/bin/sh 
echo "STARTING" 
./dosleep 
echo "BACK" 
$ ./doit.sh 
STARTING 
started. 
stopping 

^C^C^C^C^C^C 

Warum verhalten sich Terminal und Skript so unterschiedlich? Gibt es eine Möglichkeit, dieses Verhalten zu ändern?

Danke, Karl

Antwort

1

Auftragssteuerung ist off-by-default in noninteractive Schalen, aber man kann es explizit aktivieren:

set -m 

Wenn wir also Ihr Skript ändern, entweder die set -m Zeile hinzufügen oder ein -m auf dem shebang wie folgt:

#!/bin/bash -m 
./start-delay 
echo BACK 

... dann BACK emittiert nach stopping.


von der Seite bash man section on set, Betonung hinzugefügt Zitiert:

-m-Monitor-Modus. Die Jobsteuerung ist aktiviert. Diese Option ist standardmäßig für interaktive Shells auf Systemen aktiviert, die sie unterstützen (siehe JOB CONTROL oben). Alle Prozesse werden in einer separaten Prozessgruppe ausgeführt. Wenn ein Hintergrundjob abgeschlossen ist, gibt die Shell eine Zeile aus, die den Beendigungsstatus enthält.

+0

danke - funktioniert auch in der busybox shell! – Charly

+0

Wenn Sie das Skript nicht aus der Login-Shell aufrufen, müssen Sie es mit 'setsid sh -c 'myscript.sh Charly

+0

@Charly, ... nun, nicht so sehr" nicht von der Login-Shell "als" von irgendwo ohne TTY ". Die beiden sind etwas orthogonal - es ist möglich, eine Login-Shell ohne TTY oder eine TTY ohne Login-Shell zu haben. –