2013-06-01 3 views
8

Zusammenfassung: Ich habe ein Bash-Skript, das einen Prozess im Hintergrund ausgeführt wird, und soll als normaler Befehl und in einem Befehlsersatzblock wie als $(...). Das Skript selbst erzeugt einen Prozess, der zum Hintergrund führt. Es kann zu diesem Testfall reduziert werden:

#!/bin/sh 
echo something 
sleep 5 & 

in einer Shell dieses Skript ausführen, wird sofort wieder (und Druck „etwas“), ist es innerhalb $(...) läuft für 5 Sekunden, wartete auf den backgrounded „Schlaf“ hängen beenden.

Gilt für alles, was in der Shell für die Befehlsersetzung und die Prozesse im Hintergrund gestartet wird, einschließlich aller untergeordneten Elemente in diesem Prozessbaum. Scheint sowohl bash als auch zsh zu beeinflussen, habe andere nicht ausprobiert.


Original Frage: Ich habe ein Bash-Skript, das einen Wert nach stdout schreiben soll, und kopieren Sie sie auch auf die X-Zwischenablage jedes Mal, es läuft.

#!/bin/sh 
echo something 
echo something | xclip -selection clipboard 

Dieses Skript (nennen wir es „etwas“) soll verwendet werden, um dieses Wort zu bekommen (die eigentlich der Ausgang eines anderen Befehls ist) und auf unterschiedliche Weise verwendet werden, wie zum Beispiel:

$ something 
something 
$ xclip -o -selection clipboard 
something 
$ echo $(something) 
^C 

Druckt auf normales stdout, kopiert die Ausgabe in die Zwischenablage, um in normalen X-Anwendungen verwendet zu werden, und sollte auch in der Lage sein, das stdout mit bash-Befehlsersatz zu verwenden, um dieses Wort in die Mitte eines Befehls einzufügen.

Die Bash-Befehlsersetzung scheint jedoch xclip zu zwingen, im Vordergrund am Leben zu bleiben. xclip dämmt sich normalerweise selbst, da die X-Zwischenablage erfordert, dass ein Client den Inhalt der Zwischenablage bereitstellt, und das Standardverhalten ist, dass er beendet wird, sobald der Inhalt der Zwischenablage ersetzt wurde.

Nach dieser Frage hat mit xclip ich den minimalen Testfall gemacht, dass ich am Anfang dieser Frage geschrieben, so ist es, dass alles gelten scheint, die innerhalb des $(...) Schals daemonizes

Kann jemand dieses Verhalten erklären? Kann ich es irgendwie vermeiden?

Antwort

12

Wenn der Hintergrundprozeß die Befehlsersetzung nicht beeinträchtigen soll, müssen Sie die Stdout-Verbindung trennen. Dies wird sofort zurück:

$ cat bg.sh 
#!/bin/sh 
echo before 
sleep 5 >/dev/null & 
echo after 
$ date; x=$(./bg.sh); date; echo "$x" 
Sat Jun 1 13:02:26 EDT 2013 
Sat Jun 1 13:02:26 EDT 2013 
before 
after 

Sie verlieren die Fähigkeit, die backgrounded Prozess stdout zu erfassen, aber wenn Sie es im Hintergrund laufen lassen Sie wahrscheinlich egal. Der Prozess bg.sh kann immer auf die Festplatte schreiben.

+0

Woo! Perfekte und extrem einfache Lösung. Vielen Dank! – dequis

+0

Übrigens, die Umleitung zu einer Datei anstelle von/dev/null scheint zu funktionieren, um die Ausgabe zu erfassen, aber zumindest hier scheint die Ausgabedatei erst aktualisiert zu werden, nachdem der Hintergrundprozess beendet wurde. (Ich brauche es dafür aber nicht) – dequis