
Ich habe eine Anwendung, die mit und ohne '&' einwandfrei läuft, wenn sie direkt vom Terminal ausgeführt wird. Wenn ich jedoch versuche, sie von einem Shell-Skript aus auszuführen, funktioniert sie nur, wenn das abschließende '&' übersprungen wird. Daher kann ich diesen Prozess nicht im Hintergrund aus dem Shell-Skript heraus starten.
<Path to My application> <options> &
Das Anwendungsfenster wird geöffnet, danach werden jedoch keine weiteren Schritte ausgeführt.
(Die Anwendung ist eine (von mir) geänderte Version von qemu 0.13.0. Wenn ich davon im Hintergrund in einem Shell-Skript ein Disk-Image ausführe, bleibt ein schwarzer Bildschirm hängen.)
Antwort1
Es ist nicht nötig, die Anwendung mit dem Et-Zeichen in den Hintergrund zu stellen, wenn es dafür eine integrierte Option gibt. Dies ist bei qemu der Fall (sofern Sie es nicht entfernt haben):
% qemu-kvm --help | grep daemon
-daemonize daemonize QEMU after initializing
Antwort2
Sehen Sie eine Nachricht wie
[1] suspended (tty output) myapplication
im Terminal? Diese Meldung bedeutet, dass Ihr Programm versucht, vom Terminal zu lesen (wahrscheinlich, weil es von seiner Standardeingabe liest). Da nur ein Vordergrundprogramm vom Terminal lesen kann, wird das Programm angehalten.
Wenn Sie diese Meldung sehen, finden Sie heraus, warum Ihr Programm liest. Versuchen Sie in der Verzweiflung, die Standardeingabe umzuleiten ( myapplication </dev/null
).
Wenn Sie keine solche Meldung sehen, liegt ein anderer Fehler in Ihrem Programm vor. Sehen Sie sich in einem Debugger oder mit an, was Ihr Programm macht strace
.
Antwort3
Es besteht ein Unterschied zwischen der Ausführung eines Hintergrundbefehls vom Terminal und von einem Shell-Skript aus.
In einer nicht interaktiven Shell (mit deaktivierter Jobsteuerung) wird die Standardeingabe eines im Hintergrund ausgeführten Befehls implizit von umgeleitet /dev/null
, was dazu führen kann, dass Ihr Befehl überhaupt nicht ausgeführt wird.
Den POSIX-Standard finden Sie auf derShell-Befehlssprache: Asynchrone Listen.
# compare where fd 0 is pointing to
sh -c 'sleep 10 & lsof -p ${!}'
sh -c 'sleep 10 0<&0 & lsof -p ${!}'
sh -c 'set -m; sleep 10 & lsof -p ${!}'
sh -ic 'sleep 10 & lsof -p ${!}'