2012-04-05 9 views
3

Ich bin neu zu schälen, ich habe gerade erfahren, dass die Verwendung (Befehl) einen neuen Sub-Shell schaffen und den Befehl exec, so dass ich versuchen, die pid des Vater Shell und Subshell zu drucken:über Shell und Subshell

#!/bin/bash 

echo $$ 
echo "`echo $$`" 
sleep 4 
var=$(echo $$;sleep 4) 
echo $var 

Aber die Antwort ist:

$./test.sh 
9098 
9098 
9098 

Meine Fragen sind:

  1. Warum nur drei Echo druckt? Es gibt 4 Echos in meinem Code.
  2. Warum drei pids gleich sind? Subshells Pid ist offensichtlich nicht identisch mit dem seines Vaters.

Vielen Dank für Antworten :)

Antwort

6

Zuerst wird die Zuordnung erfasst Standardausgabe des Kindes und legt es in var, anstatt sie zu drucken:

var=$(echo $$;sleep 4) 

Dies kann gesehen mit:

$ xyzzy=$(echo hello) 
$ echo $xyzzy 
hello 

Zweitens, all diese $$ Variablen werden in der aktuellen Shell ausgewertet, was bedeutet, dass sie in die aktuelle PID vor Kinder Start umgewandelt werden. Die Kinder sehen die PID, die bereits generiert wurde. Mit anderen Worten, die Kinder führen echo 9098 anstatt echo $$ aus.

Wenn Sie die PID des Kindes wollen, müssen Sie eine Übersetzung in der Mutter verhindern, beispielsweise durch Verwendung von einfachen Anführungszeichen:

bash -c 'echo $$' 
+1

Wenn Sie "man bash" konsultieren, Antwort die Informationen in paxdiablo die unter den Positionen Befehl Substitution und Spezielle Parameter gefunden wird. – minopret

+0

Ich würde zwei Dinge hinzufügen: 1.dass es im Code * 5 * Echos gibt, von denen zwei als Strings erfasst werden (ein Echo wird sofort, das andere in var gespeichert). 2. In bash 4.0 und höher wird die Umgebungsvariable "$ BASHPID" die PID der Subshell ausgeben. Bash 4.0 ist noch nicht üblich, versuchen Sie bash --version, um Ihre zu sehen. – Mike

+0

cool, danke viel ~ – Coaku

0
echo "one.sh $$" 
echo `eval echo '$$'` 

ich die oben erwarten verschiedene PIDs zu drucken, aber es tut es nicht. Es erstellt einen Kindprozess. Verifiziert durch Hinzufügen von Schlaf in ``.

echo "one.sh $$" 
echo `eval "echo '$$'";sleep 10` 

auf der oben von einem Skript ausgeführt und ps zeigt zwei processs one.sh (Name des Skripts) und Schlaf läuft.

USER  PID %CPU %MEM VSZ RSS TTY  STAT START TIME COMMAND 
test 12685 0.0 0.0 8720 1012 pts/15 S+ 13:50 0:00  \_ bash one.sh 
test 12686 0.0 0.0 8720 604 pts/15 S+ 13:50 0:00   \_ bash one.sh 
test 12687 0.0 0.0 3804 452 pts/15 S+ 13:50 0:00    \_ sleep 10 

Dies ist die erzeugte Ausgabe

one.sh 12685 
12685 

nicht sicher, was mir fehlt.

+0

Bash ist hinterhältig, entscheidet, was '$$' beim Start erweitert und dann behält es in allen Unterschalen es gabelt. (Dies ist, soweit ich weiß, absichtlich, um die Erweiterung gleich zu halten, z. B. für die Benennung temporärer Dateien.) – torek

+0

[Es geht darum.] (Http://stackoverflow.com/questions/7858191/difference -zwischen-bash-pid-und) – tuxuday

-1

Die Lösung ist $!. Wie in:

#!/bin/bash 

echo "parent" $$ 
yes > /dev/null & 
echo "child" $! 

Ausgang:

$ ./prueba.sh 
parent 30207 
child 30209 
Verwandte Themen