Ich bin auf Debian GNU / Linux 9. Ich weiß, /proc
ist etwas Besonderes , ich weiß, was /proc/self
ist .
Dieser Befehl
sh -c '/bin/cat /proc/self/comm - </proc/self/comm'
ergibt
cat
sh
Das Muster wird ähnlich sein, wenn ich dash
anstelle von verwende sh
. Aber mit bash
, ksh
oder zsh
das Ergebnis
cat
cat
Nehmen /proc/self/stat
statt /proc/self/comm
ich kann bestätigen, dass die zwei cat
-s in der Tat der gleiche einzelne Prozess sind. Anscheinend unterscheiden sich die Muscheln unter der Haube, es ist in Ordnung. Jetzt nehmen wir
sh -c '/bin/cat /proc/self/environ - </proc/self/environ'
Nachdem ich das Obige beobachtet habe, mit sh
oder dash
ich erwarte, die Umgebung der cat
ersten, die Umgebung der Shell später zu sehen. Es scheint zu funktionieren (beide Umgebungen sind höchstwahrscheinlich sowieso identisch, daher ist es schwer zu sagen, ob alles wie erwartet funktioniert, aber mein Punkt ist: Keine environ
ist leer).
Mit bash
, ksh
oder zsh
ich erwarte, die Umgebung cat
zweimal zu sehen, aber es wird nur einmal gedruckt . Aufteilung in zwei getrennte Fälle:
bash -c '/bin/cat - </proc/self/environ'
druckt nichts, als wäreenviron
es leer;bash -c '/bin/cat /proc/self/environ'
druckt etwas wie erwartet.
Was ist los? Dies ist bei comm
oder nicht der Fall stat
. Warum ist environ
anders?
$ uname -a
Linux barbaz 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1 (2018-04-29) x86_64 GNU/Linux
quelle
Antworten:
Die Unterschiede zwischen den Schalen sind auf Unterschiede im Prozessaufbau zurückzuführen.
dash
Richtet Umleitungen vor dem Gabeln ein und/proc/self
zeigt auf die Schale.bash
undzsh
richten Sie sie nach dem Gabeln ein, damit Sie/proc/self
auf den neuen Prozess hinweisen . Sie können dies sehen mitstrace -f
:strace -f dash -c '/bin/cat /proc/self/comm - </proc/self/comm'
Shows (unter anderem)(
/proc/self/comm
wird vor demclone
Systemaufruf geöffnet , in dem sich der Prozess teilt);strace -f bash -c '/ bin / cat / proc / self / comm -
(
/proc/self/comm
wird nach demclone
Aufruf im untergeordneten Prozess 8106 geöffnet ).Um zu verstehen, warum
environ
leer angezeigt wird, ist etwas mehr Erklärung erforderlich. Beim/proc/<pid>/environ
Öffnen speichertmm_struct
der Kernel eine Kopie des Zeigers auf die Aufgabe , die Zeiger auf die Umgebung enthält. Mitexecve
dem zum Starten descat
Prozesses wird jedoch ein neuermm_struct
Prozess erstellt . Somit zeigt die Umleitung auf veraltete Informationen und wenn siecat
ihre Eingabe liest, sieht sie ihre reale Umgebung nicht. Die Umgebung, die es sieht , sollte eine Kopie der übergeordneten Umgebung sein, aber die beteiligten Shells bereinigen sie, bevor die neue Umgebung (die von eingerichtet wirdexecve
) gegabelt und eingerichtet wird .quelle