Ich habe ein Bash-Skript foocaller
, das ein Ruby-Skript aufruft foo
:
Abonnieren
/path/to/foo
Innerhalb foo
möchte ich den Pfad von erhalten foocaller
. Nachdieser Vorschlag, dazu habe ich den folgenden Code eingegeben:
foo
#!/usr/bin/env ruby
puts File.read("/proc/#{Process.ppid}/cmdline")
Wenn ich laufe:
$ bash foocaller
dann bekomme ich das gewünschte:
bash^@/path/to/foocaller
aber wenn ich direkt aufrufe foocaller
:
$ foocaller
dann bekomme ich das:
/bin/bash^@--noediting^@-i
der den Pfad zu nicht anzeigt foocaller
. Wie kann ich den Pfad zu erhalten, foocaller
indem ich direkt foocaller
ohne aufrufe bash
?
Antwort1
Viele Shells optimieren den letzten Befehl in einem Skript, indem sie den Befehl im selben Prozess ausführen:
$ sh -c 'ps
ps'
PID TTY TIME CMD
32673 pts/3 00:00:00 zsh
32696 pts/3 00:00:00 sh
32697 pts/3 00:00:00 ps
PID TTY TIME CMD
32673 pts/3 00:00:00 zsh
32696 pts/3 00:00:00 ps
Sehen Sie, wie das zweite Element ps
im ursprünglich laufenden Prozess sh
(32696) ausgeführt wurde und dass sein übergeordnetes Element dann das sh
übergeordnete Element von ist (in meinem Fall hier zsh
meine interaktive Shell).
Sie können dies vermeiden, indem Sie eine exit
Zeile hinzufügen:
#! /bin/sh -
foo
exit
sh
kann nicht im selben Prozess ausgeführt werden , da es nach Abschluss foo
noch weitere Interpretationen gibt . Daher wird es stattdessen in einem anderen Prozess ausgeführt und wartet darauf. Und dann ausgeführt (wodurch das Skript mit demselben Beendigungsstatus wie von beendet wird ).foo
foo
exit
foo
Das ist nun nicht ganz optimal, da man hier einen Vorgang hätte einsparen können.
Eine bessere Möglichkeit, foo
den Pfad zu kennen, foocaller
könnte sein, ihn wie folgt anzugeben:
#! /bin/sh -
CALLER=$0 foo
Anschließend foo
können Sie die Umgebungsvariable abfragen CALLER
, um den Pfad ihres Aufrufers zu erhalten ( import os;print(os.environ["CALLER"])
in Python).