Nach meinem Wissen, um die aktuelle Shell zu bestimmen, die wir echo $0
in der Shell verwenden. Ich möchte vielmehr, dass mein Skript überprüft, in welcher Shell es ausgeführt wird. Also habe ich versucht, $0
das Skript auszudrucken und es gibt den Namen des Skripts zurück, wie er sollte. Meine Frage ist also, wie kann ich herausfinden, in welcher Shell mein Skript zur Laufzeit ausgeführt wird?
22
echo $0
ist hier keine Option, da das Skript auf vielen verschiedenen Computern ausgeführt wird, auf denen ich als erstes die Shell überprüfen muss.#! /bin/sh -
, wird es ausgeführtsh
. Meinen Sie, von welcher Variantesh
es ist?Antworten:
Unter Linux können Sie verwenden
/proc/PID/exe
.Beispiel:
quelle
/bin/sed -r -e 's/\x0.*//' /proc/$$/cmdline
gibt stattdessen zsh oder ksh. (Das wäre $ 0, wenn Shells dies nicht auf magische Weise korrigiert hätten, um stattdessen den Namen des Skripts zu vergeben.)/proc
ist so hässlich und unportabel wie es nur geht./proc
ist nicht 'hässlich'./proc
ist oft eine sehr elegante Lösung. Nicht portierbar ja, aber weil etwas nicht portierbar ist, macht es es nicht hässlich./proc
hässlich, da die darin enthaltenen Dateien nach Lust und Laune der Entwickler verschoben werden können und der Inhalt von Dateien sich ohne Vorankündigung ändern kann.Vielleicht nicht das, wonach Sie fragen, aber dies sollte bis zu einem gewissen Grad funktionieren, um den Interpreter zu identifizieren, der es derzeit für einige interpretiert, wie Thompson (osh), Borowski, Borowski-again (bash), Korn (ksh88, ksh93, pdksh, mksh) ), zsh, Policy-compliant Ordinary (posh), Noch eine (yash), rc, akanga, es shells, wish, tclsh, expect, perl, python, ruby, php, JavaScript (mindestens nodejs, SpiderMonkey-Shell und JSPL) , MS / Wine cmd.exe, command.com (MSDOS, FreeDOS ...).
Ich habe die erste Version des which_interpreter- Skripts von 2004 im Usenet gepostet . Sven Mascheck hat ein (für Sie wahrscheinlich nützlicheres) Skript namens Whatshell , das sich auf die Identifizierung von Bourne-ähnlichen Shells konzentriert. Sie können auch eine fusionierte Version unserer beiden Skripte finden dort .
quelle
print
es in eine Funktion.bash 3.2.53(1)-release
als der Interpreter identifiziert , der es interpretiert.Dies ist, was ich in meinem .profile verwende, um nach verschiedenen Shells auf den Systemen zu suchen, auf denen ich arbeite. Es macht keine feinen Unterschiede zwischen ksh88 und ksh93, aber es hat mich nie im Stich gelassen.
Beachten Sie, dass keine einzige Gabel oder Rohr erforderlich ist.
quelle
ksh93
haben$KSH_VERSION
. Diese Variable stammt vonpdksh
und hat es nie zu AT & T ksh88 geschafft.FCEDIT
.posh
(pdksh, bei dem die meisten Nicht-POSIX-Funktionen entfernt wurden, sodass Sie es wahrscheinlich als "sh" bezeichnen möchten) weder FCEDIT noch KSH_VERSION hat, aber PS3 (möglicherweise nicht lange), obwohl es unwahrscheinlich ist, dass es als Anmeldeshell fungiert . Beachten Sie auch , dass der obige Code würde nicht überlegen , obbash
oderzsh
insh
Emulationsmodus, was ein Problem sein kann , wenn Sie verwenden ,$PROFILE_SHELL
ob oder nicht zu entscheiden , diese oder jene Funktion zu aktivieren. Weitere Informationen finden Sie unter Sven Maschecks Whatshell .Du könntest es versuchen
Hiermit erhalten Sie den Namen des Befehls, der der pid des Skripts zugeordnet ist.
quelle
cmd
zu ,comm
wenn POSIXifying die Antwort.Wenn der
lsof
Befehl auf Ihrem System verfügbar ist, können Sie den vollständigen Pfad der ausführbaren Datei der übergeordneten Shellps
abrufen, indem Sie die übergeordnete PID über abrufen und die Ausgabe von analysierenlsof -p $ppid
(siehe So ermitteln Sie die aktuelle Shell, an der ich arbeite? ).quelle
/
, wenn ichNR==4
den Pfad zum übergeordneten Shell-Element erhalte.sh
die$PPID
Variable haben. EinLinux
, können Sie verwendenreadlink -f "/proc/$PPID/exe"
.Außerhalb von Linux oder ohne Zugriff auf das / proc-Dateisystem oder ein gleichwertiges System können Sie pstree verwenden:
Vorausgesetzt, Sie haben die PID von
Auf einem Mac:
Auf einer Linux-Box:
Das Format und der Stil der Ausgabe von pstree unterscheiden sich je nach Ihrer Umgebung, Sie können jedoch die ASCII-Ausgabe erzwingen und dann sed / tr / awk / etc. Filtern Sie die Ausgabe, um die Shell abzurufen, in der das Skript ausgeführt wird.
Also eine aufgeräumte Ausgabeversion (funktioniert für Mac oder Linux OS):
Lauferträge:
Und wenn mit einer anderen Shell ausgeführt:
Erträge:
Kein root oder spezielles Dateisystem erforderlich. Beachten Sie, dass meine Filterung davon ausgeht, dass der Shell-Binärname mit sh endet und dass es keine Zwischeneinträge gibt, die mit sh enden. Es wird auch davon ausgegangen, dass Sie Ihr Skript nicht "sh" oder ein unglückliches Grep-Muster genannt haben, das Informationen verwischt. :) Erfordert einige Anpassungen für Ihre eigene Umgebung, um ein höheres Maß an Narrensicherheit zu gewährleisten.
quelle
Sie können den Befehl verwenden:
um die Shell aus dem Skript herauszufinden.
quelle
$SHELL
ist die Shell der Wahl des Benutzers. Initialisiert aus der Login-Shell des Benutzers. Mit der aktuell laufenden Shell nichts zu tun.