Ich muss den Pfad eines bestimmten Programms über die PATH
Verwendung eines Shell-Skripts finden. Der Pfad muss der tatsächliche vollständige Pfad des Programms sein, der später an eine der exec*
Funktionen übergeben werden kann, die das Programm selbst nicht durchsucht PATH
, z execv
.
Es gibt Programme wie kill
, die als aktuelles Programm und gleichzeitig als eingebaute Shell zur Verfügung stehen. In diesem Fall benötige ich den vollständigen Pfad zum eigentlichen Programm.
PATH
Wie in Abschnitt 2.9.1.1, Befehlssuche und Ausführung des POSIX-Standards beschrieben, gibt es mehrere Dienstprogramme, die ein Programm auf der finden können .
Es gibt which
, was zu keinem Standard gehört. Bei einigen Systemen kann es sich um ein reguläres Programm handeln, bei einigen Shells um ein eingebautes Programm. Es scheint auf den meisten Systemen und Shells verfügbar zu sein, aber die Shells mit einer integrierten Version geben statt des Pfads zur ausführbaren Datei nur den Namen der integrierten Version zurück. Es ist auch in keiner Weise standardisiert und kann Ausgaben zurückgeben und verschiedene Optionen annehmen.
bash# which kill
/usr/bin/kill
dash# which kill
/usr/bin/kill
fish# which kill
/usr/bin/kill
mksh# which kill
/usr/bin/kill
tcsh# which kill
kill: shell built-in command.
zsh# which kill
kill: shell built-in command
Es gibt whence
, die ein paar Muscheln eingebaut ist. Bei vielen Shells jedoch nicht verfügbar. Es wird auch der Name des eingebauten anstelle des Pfades zum Programm zurückgegeben. A -p
kann an wherece übergeben werden, um dieses Verhalten zu ändern.
bash# whence kill
bash: whence: command not found
dash# whence kill
dash: 1: whence: not found
fish# whence kill
fish: Unknown command 'whence'
mksh# whence kill
kill
mksh# whence -p kill
/usr/bin/kill
tcsh# whence kill
whence: Command not found.
zsh# whence kill
kill
zsh# whence -p kill
/usr/bin/kill
Es gibt das command
von POSIX spezifizierte Builtin: 2008 . Leider sucht es auch nach regulären Befehlen und eingebauten Funktionen und gibt den Namen der eingebauten Funktion anstelle des Pfads zu dem Programm zurück, der von einer eingebauten Funktion mit dem gleichen Namen beschattet wird. Einige alte Shells haben es noch nicht implementiert.
bash# command -v kill
kill
dash# command -v kill
kill
fish# command -v kill
/usr/bin/kill
mksh# command -v kill
kill
tcsh# command -v kill
command: Command not found.
zsh# command -v kill
kill
enable
in POSIX angegeben ist oder nicht, aber wenn ja, können Sieenable -n which
die integrierte Shell für deaktivierenwhich
.realpath
enable
wird nur vonbash
undzsh
type -p
. Sowohl bash als auch dash lassen Siecommand
befehlen, eine aktuelle ausführbare Datei auszuführen, selbst wenn es eine Funktion oder ein eingebautes Programm mit demselben Namen gibt.command
überspringt Funktionen (und Aliase), aber KEINE eingebauten Funktionen, wie im Q korrekt angegeben. Und Sie können nicht immer einen Shebang verwenden, da es auf allen Systemen keinen Pfad gibt, der eine bestimmte Shell oder sogar eine POSIX-Shell abruft.Antworten:
Suchen Sie einfach selbst danach.
Geprüft
bash
,dash
,ksh
,mksh
,zsh
Aktualisieren
Das Obige ist für ein eigenständiges Skript hilfreich. Wenn Sie dies jedoch in ein größeres Skript einbetten möchten, möchten Sie möglicherweise etwas Ähnliches wie das Folgende verwenden.
Dies ist so, dass
IFS
nach dem Auffinden der Übereinstimmung auchexit
's mitreturn
' s getauscht wirdquelle
IFS
Variable exportieren ? Ist es nicht genug, dieses Set in der lokalen Shell zu haben? Apropos lokal, wärelocal IFS
portabel? Das Obige kann schlecht interagieren, wenn etwas anderes IFS auf die gleiche Weise speichert. Wenn Sie sich diese Frage zu SE ansehen ,local
funktioniert sie möglicherweise für die meisten Shells, obwohl sie nicht POSIX sind. Das Einfügen der Originalversion in eine(…)
Subshell kann ebenfalls funktionieren.