Wie kann ich testen, welche Shell ich in einem Terminal verwende?

69

Wie überprüfe ich, welche Shell ich in einem Terminal verwende? Welche Shell verwende ich in MacOS?

user5837
quelle
2
@xenoterracide: mindestens unix.stackexchange.com/questions/3645/… . Die Antwort von Geekosaurier ist vollständiger, daher habe ich dafür gestimmt, die vorherige Frage zu schließen.
Gilles
1
echo $ SHELL, nein?
unschuldige Welt
@ unschuldige-welt Nein, echo #SHELList es nicht ganz. Siehe # 3 in der Antwort von Geekosaurier .
Basil Bourque
Ich bin mir nicht so sicher, ob "Shell" eine genau definierte Bedeutung hat. Zum Beispiel könnten Sie laufen, xterm -e /bin/cat aber ich bin nicht glücklich, /bin/cateine Shell aufzurufen .
Basile Starynkevitch
Auch einige Shells (wie scsh ) verwenden keine POSIX-Shell-ähnliche Syntax.
Basile Starynkevitch

Antworten:

71

Mehrere Möglichkeiten, von am wenigsten zuverlässig (und am wenigsten "schwer"):

  1. ps -p$$ -ocmd=. (Unter Solaris muss dies möglicherweise fnameanstelle von erfolgen cmd. Unter OSX und unter BSD sollte dies commandanstelle von erfolgen cmd.)
  2. Suchen Sie nach $BASH_VERSION, $ZSH_VERSIONund anderen Shell-spezifischen Variablen.
  3. Überprüfen Sie $SHELL; Dies ist ein letzter Ausweg, da es Ihre Standard- Shell und nicht unbedingt die aktuelle Shell angibt .
Geekosaurier
quelle
4
Sollten Sie auch erwähnen $0?
Mikel
Ich mag es nicht, $0weil es komplizierter ist: (1) es kann nur der Basisname sein, (2) es kann ein '-' auf der Vorderseite haben, um es als Anmeldeshell zu kennzeichnen.
Geekosaurier
ps -p$$ -ocmd=""ist
schöner
1
@geekosaur: vielleicht doch $0nützlicher als $SHELL: stimmst du nicht zu? Sie können es jederzeit durchleiten sed, um das '-' zu entfernen.
Iconoclast
2
Wenn Sie laufen tcsh, $tcshund $versionwird eingestellt. Dies sind Shell-Variablen, keine Umgebungsvariablen. Wenn Sie eine Nicht-tcsh-Version von ausführen csh, gibt es meines Erachtens keine eindeutigen Variablen. Und natürlich unterscheidet sich die Syntax zum Überprüfen von Variablen zwischen csh / tcsh einerseits und sh / ksh / bash / zsh andererseits.
Keith Thompson
41

Ich habe festgestellt, dass die folgenden Funktionen in den vier Shells funktionieren, die ich auf meinem System installiert habe (bash, dash, zsh, csh):

$ ps -p $$

Das Folgende funktioniert auf zsh, bash und dash, aber nicht auf csh:

$ echo $0
Steven D
quelle
2
Funktioniert auch nicht bei Fischen.
Ron E
Ich denke, dass die Antwort von @ jiliagre wahrscheinlich ist, würde ich heute verwenden. Auf Fisch %selfkann anstelle von$$
Steven D
8

Da die Frage nach der verwendeten Shell fragt und nicht über die potenziellen Argumente spricht, die an sie übergeben werden, können Sie sie auf folgende Weise nicht anzeigen:

$ ps -o comm= -p $$
ksh93 
jlliagre
quelle
6

Ein Hinweis zu einigen leichteren Implementierungen (Android-Telefone, Busybox usw.): psDer -pSwitch wird nicht immer unterstützt , aber Sie können die Suche mit einem Befehl wie dem folgenden durchführen ps | grep "^$$ ". (Dieser grepreguläre Ausdruck identifiziert die PID eindeutig, so dass es keine falsch positiven Ergebnisse gibt.

Kumpelschwimmen
quelle
7
ps | grep $$kann immer noch falsch positive Ergebnisse liefern, wenn beispielsweise Ihr aktueller Prozess ein Prozess ist 1234und es einen gibt 12345.
Keith Thompson
4

Es gibt zwei sehr einfache Möglichkeiten:

  • Verwenden des Befehls ps :

    ps -o comm= $$

    oder

    ps -h -o comm -p $$

    wo:

    • -hoder beenden Sie alle Optionen mit, =um keine Kopfzeile anzuzeigen.
    • -o commzum Anzeigen nur des Prozessbasisnamens ( bashanstelle von /bin/bash).
    • -p <PID> Liste nur verarbeiten, wenn PID-Formularliste vorhanden ist.
  • Verwenden des / proc- Prozessinformations-Pseudodateisystems:

    cat /proc/$$/comm

    Diese Option verhält sich genau wie der psobige Befehl.

    oder

    readlink /proc/$$/exe

    Dieser /proc/PID/exeLink verweist auf die auszuführende Datei, die in diesem Fall auf / bin / bash, / bin / ksh usw. verweist.

    Um nur den Namen der Shell zu erhalten, können Sie einfach verwenden

    basename $(readlink /proc/$$/exe)

    Dies ist die einzige Option, die immer das gleiche Ergebnis liefert, auch wenn Sie sich in einem Skript, Quellcode oder Terminal befinden, das auf die Binärdatei des verwendeten Shell-Interpreters verweist.

    Warnung Sie müssen sich bewusst sein, dass dies die ultimative Binärdatei anzeigt, sodass ksh möglicherweise mit ksh93 oder sh mit bash verknüpft ist.

Die Verwendung von /procist wirklich nützlich über die /proc/self, die auf die PID des aktuellen Befehls verweist.

David Goitia
quelle
3

Eine Mischung aus all den anderen Antworten, die mit Mac (comm), Solaris (fname) und Linux (cmd) kompatibel sind:

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1
sebastien
quelle
das gibt mir meinen aktuellen Verzeichnisnamen; auch unter cshund tcshes gibt mirAmbiguous output redirect.
iconoclast
2

Wenn Sie es in Ihren Umgebungsvariablen gespeichert haben, können Sie Folgendes verwenden:

echo $SHELL
jasonleonhard
quelle
Das wird höchstwahrscheinlich den Pfadnamen der Shell-Programmdatei Ihrer Login-Shell zurückgeben. Es ist jedoch nicht sicher, ob die Login-Shell das ist, was Sie gerade ausführen.
Kusalananda
1

Die PID der laufenden Shell wird durch die Variable $$ angegeben (in den meisten Shells).

whichsh="`ps -o pid,args| awk '$1=='"$$"'{print $2}'`"
echo "$whichsh"

Mit Backticks jsh (Heirlomm-Shell) zum Laufen bringen.

In vielen Schalen ps -o args= -p $$funktioniert der direkte Test , busybox ashscheitert aber daran (gelöst).

Die Prüfung, $1die gleich sein muss, $$entfernt die meisten Fehlalarme.

Die letzten ;:werden verwendet, um die Shell für ksh und zsh am Laufen zu halten.

Tests auf weiteren Systemen helfen, bitte geben Sie einen Kommentar ab, wenn dies bei Ihnen nicht funktioniert.

Funktioniert nicht in cshArt von Muscheln.


quelle
Unter OS / X erhalte ich in meinen Tests mindestens drei Zeilen, eine für die Shell, eine für /usr/lib/dyld, eine für /private/var/db/dyld/dyld_shared_cache_x86_64.
Stéphane Chazelas
Ja, jetzt werden nur die Einträge in / bin und / usr / bin ausgewählt
Stéphane Chazelas
@ StéphaneChazelas Vielleicht ist es jetzt besser?
0

Ich stelle $MYSHELLfür zukünftige Tests in meinem Shell-Agnostiker ein ~/.aliases:

unset MYSHELL
if [ -n "$ZSH_VERSION" ] && type zstyle >/dev/null 2>&1; then        # zsh
  MYSHELL=`command -v zsh`
elif [ -x "$BASH" ] && shopt -q >/dev/null 2>&1; then                # bash
  MYSHELL=`command -v bash`
elif [ -x "$shell" ] && which setenv |grep builtin >/dev/null; then  # tcsh
  echo "DANGER: this script is likely not compatible with C shells!"
  sleep 5
  setenv MYSHELL "$shell"
fi

# verify
if [ ! -x "$MYSHELL" ]; then
  MYSHELL=`command -v "$(ps $$ |awk 'NR == 2 { print $NF }')"`
  [ -x "$MYSHELL" ] || MYSHELL="${SHELL:-/bin/sh}"  # default if verify fails
fi

Es tcshist unwahrscheinlich, dass der Abschnitt in ein POSIX-ähnliches Skript passt, da er sich grundlegend unterscheidet (also die Warnung und die Pause von fünf Sekunden). (Zum einen können csh-Style-Shells nicht 2>/dev/nulloder >&2, wie im berühmten Csh Programming Considered Harmful Rant erwähnt, nicht.)

Adam Katz
quelle
-1

Sie können einfach den echo $0Befehl verwenden, um zu überprüfen, welche Shell Sie verwenden, und <name_of_the_shell> --versionum die Version der Shell zu überprüfen. (zB bash --version).

Sachin C
quelle
Steven D hat es bereits erwähnt
:)