So bestimmen Sie die aktuelle Shell, an der ich arbeite

631

Wie kann ich die aktuelle Shell bestimmen, an der ich arbeite?

Wäre die Ausgabe des psBefehls allein ausreichend?

Wie kann dies in verschiedenen Unix-Varianten erfolgen?

Josh
quelle
9
Das Testen auf bestimmte Funktionen (z. B. wird es !ersetzt?) Ist wahrscheinlich portabler als das Finden des Namens der Shell. Lokale Gewohnheit könnte Sie etwas ausführen lassen, /bin/shdas tatsächlich Asche, Bindestrich, Bash usw. sein könnte
msw
1
@msw: Scheint ein guter Kommentar zu sein, außer dass ich mich frage "wie?".
Nobar
Es scheint, dass es keine einfache Antwort auf diese Frage gibt. Wenn wir die Shell nicht abfragen können , ist es möglicherweise besser, immer die Shell anzugeben . Ich bin mir nicht sicher, ob dies immer möglich ist, aber vielleicht ist es einfacher zu erreichen, als die Leute allgemein annehmen.
Nobar
Dies könnte helfen -> opensourceforgeeks.blogspot.in/2013/05/…
Aniket Thakur
@Aniket, nicht so viel Hilfe, wie Sie vielleicht denken - das interessiert nur interaktive Shell-Prozesse.
Toby Speight

Antworten:

793
  • Es gibt drei Ansätze, um den Namen der ausführbaren Datei der aktuellen Shell zu ermitteln:

    Bitte beachten Sie, dass alle drei Ansätze getäuscht werden können, wenn die ausführbare Datei der Shell ist /bin/sh, aber es ist bashzum Beispiel wirklich eine Umbenennung (was häufig vorkommt).

    Daher wird Ihre zweite Frage, ob die psAusgabe funktioniert, mit " nicht immer " beantwortet .

    1. echo $0 - gibt den Programmnamen aus ... der im Fall der Shell die eigentliche Shell ist.

    2. ps -ef | grep $$ | grep -v grep- Hiermit wird nach der aktuellen Prozess-ID in der Liste der ausgeführten Prozesse gesucht. Da der aktuelle Prozess die Shell ist, wird sie eingeschlossen.

      Dies ist nicht 100% zuverlässig, da Sie möglicherweise andere Prozesse haben, deren psAuflistung dieselbe Nummer wie die Prozess-ID der Shell enthält, insbesondere wenn diese ID eine kleine Zahl ist (wenn die PID der Shell beispielsweise "5" ist, werden möglicherweise Prozesse aufgerufen "java5" oder "perl5" in derselben grepAusgabe!). Dies ist das zweite Problem beim "ps" -Ansatz, da man sich nicht auf den Shell-Namen verlassen kann.

    3. echo $SHELL- Der Pfad zur aktuellen Shell wird als SHELLVariable für jede Shell gespeichert . Die Einschränkung für diesen Fall ist, dass Sie stattdessen den Wert Ihrer Anmeldeshell erhalten, wenn Sie eine Shell explizit als Unterprozess starten (z. B. nicht Ihre Anmeldeshell). Wenn dies möglich ist, verwenden Sie den Ansatz psoder $0.


  • Wenn die ausführbare Datei jedoch nicht mit Ihrer tatsächlichen Shell übereinstimmt (z. B. /bin/shbash oder ksh), benötigen Sie Heuristiken. Hier sind einige Umgebungsvariablen, die für verschiedene Schalen spezifisch sind:

    • $version ist auf tcsh eingestellt

    • $BASH ist auf Bash gesetzt

    • $shell (Kleinbuchstaben) wird in csh oder tcsh auf den tatsächlichen Shell-Namen gesetzt

    • $ZSH_NAME ist auf zsh gesetzt

    • ksh hat $PS3und $PS4gesetzt, während die normale Bourne-Shell ( sh) nur hat $PS1und $PS2setzt. Dies scheint im Allgemeinen wie die am schwersten zu unterscheiden - den einzigen Unterschied in der gesamten Reihe von Umgebungsvariablen zwischen shund kshwir haben auf Solaris boxt installiert ist $ERRNO, $FCEDIT, $LINENO, $PPID, $PS3, $PS4, $RANDOM, $SECONDS, und $TMOUT.

DVK
quelle
$ {. sh.version} wird auf ksh93
fpmurphy
14
ps -p $$wie Matthew Slattery betont. Für ksh: echo $KSH_VERSIONoder echo ${.sh.version}.
Bis auf weiteres angehalten.
@Dennish - mein ksh hat momentan keine KSH_VERSION gesetzt. und echo ${.sh.version}gibt "Bad Substitution" zurück. Siehe meine Lösung oben
DVK
3
" ps -ef | grep …... Dies ist nicht 100% zuverlässig als ..." Die Verwendung eines einfachen regulären Ausdrucks über egrepoder grep -ekann die Zuverlässigkeit auf 100% für alle Zwecke und Zwecke erhöhen : ps -ef | egrep "^\s*\d+\s+$$\s+". Das ^stellt sicher, dass wir am Anfang der Zeile beginnen, dass die \d+UID aufgefressen wird, dass $$die PID übereinstimmt und dass \s*und \s+Leerzeichen zwischen den anderen Teilen berücksichtigt und sichergestellt werden.
Slipp D. Thompson
2
@ SlippD.Thompson funktionierte nicht in GNU / Linux. Aber das scheint zu funktionieren:ps -ef | awk '$2==pid' pid=$$
jarno
97

ps -p $$

sollte überall funktionieren, wo die Lösungen involviert sind ps -efund grepfunktionieren (bei jeder Unix-Variante, die POSIX-Optionen für unterstütztps ) und nicht unter den Fehlalarmen leiden, die durch das Suchen nach einer Folge von Ziffern entstehen, die an anderer Stelle erscheinen können.

Matthew Slattery
quelle
12
Einige Shells haben eine eigene integrierte Version, psdie möglicherweise nicht verstanden wird, -psodass Sie sie möglicherweise verwenden müssen /bin/ps -p $$.
Bis auf weiteres angehalten.
12
Alle Muscheln, mit denen ich vertraut bin, verstehen, $$außer denen, fishmit denen Sie sie verwenden müssten ps -p %self.
Bis auf weiteres angehalten.
3
Eigentlich sollten Sie sich nicht auf harte Wege wie verlassen /bin/ps. pskönnte leicht (eigentlich ist es heutzutage ganz normal) eingebaut werden /usr/bin. $(which ps) -p $$ist ein besserer Weg. Natürlich funktioniert dies nicht bei Fischen und möglicherweise einigen anderen Muscheln. Ich denke, es ist (which ps) -p %selfin Fisch.
Aron Cederholm
1
In einigen minimalen Systemen wie einem Debian-Slim-Docker-Container ist ps möglicherweise nicht vorhanden. In diesem Fall funktioniert dieser Ansatz immer noch:readlink /proc/$$/exe
mxmlnkn
Wenn Ihr von shemuliert wird bash, geben ps -p Ihnen /usr/bin/bashsogar, dass Sie es alssh
Ding-Yi Chen
45

Versuchen

ps -p $$ -oargs=

oder

ps -p $$ -ocomm=
Nahuel Fouilleul
quelle
4
Dies ist eine schöne kurze. Ich habe mich benutzt ps -o fname --no-headers $$.
Anne van Rossum
Vielen Dank. Ich fand dies die beste Option in einem Skript, um Bash-spezifische Befehle zu schützen test `ps -p $$ -ocomm=` == "bash" && do_something_that_only_works_in_bash. (Die nächste Zeile in meinem Skript hat das Äquivalent für csh.)
craq
1
Ich habe festgestellt, dass wenn Sie dies innerhalb einer Subshell tun, dies zu falschen zusätzlichen Zeilen führen kann, indem die PID des Elternteils sowie der tatsächliche Shell-Prozess abgeglichen werden. Dafür benutze ich -qanstelle von -p:SHELL=$(ps -ocomm= -q $$)
Steve
35

Wenn Sie nur sicherstellen möchten, dass der Benutzer ein Skript mit Bash aufruft:

if [ ! -n "$BASH" ] ;then echo Please run this script $0 with bash; exit 1; fi
Peter Lamberg
quelle
1
Dies sollte derjenige sein, der näher an der Spitze liegt. Vielen Dank.
Alex Skrypnyk
4
Es sollte nicht näher an der Spitze sein, da es die Frage überhaupt nicht beantwortet. Wenn die Frage "Wie prüfe ich, ob das Skript unter Bash läuft" wäre, stimme ich dafür.
David Ferenczy Rogožan
2
@DawidFerenczy - Diese Frage ist das beste Ergebnis, wenn Sie nach dieser Phrase suchen. Auf lange Sicht denke ich, dass es viel wichtiger ist, dass Antworten beantworten, wonach die Leute suchen, als zu beantworten, worum es bei der ursprünglichen Frage ging.
ArtOfWarfare
3
Darüber hinaus ist die Variable $ BASH wird unter tcsh definiert , wenn die tcsh von bash aufgerufen wird
18446744073709551615
Das ist sehr nützlich, danke. Passen Sie es einfach ein wenig an und setzen Sie dies als zweite Zeile nach #!/bin/bash: if [ ! -n "$BASH" ] ;then exec bash $0; fi. Mit dieser Zeile wird das Skript mit bash ausgeführt, auch wenn es mit ksh oder sh gestartet wurde. Mein Anwendungsfall benötigt keine Befehlszeilenargumente, kann aber $0bei Bedarf nachträglich hinzugefügt werden.
Joanis
20

Du kannst es versuchen:

ps | grep `echo $$` | awk '{ print $4 }'

Oder:

echo $SHELL
Karlphillip
quelle
6
Was ist der Sinn von grep, gefolgt von awk, wann /pattern/ { action }wird es gehen?
Jens
# in zshell alias shell = 'echo $ {SHELL: t}'
SergioAraujo
4
$SHELLDie Umgebungsvariable enthält eine Shell, die für einen aktuellen Benutzer als Standard konfiguriert ist. Es spiegelt keine Shell wider, die gerade ausgeführt wird. Es ist auch besser zu verwenden, ps -p $$als $$ wegen falsch positiver Ergebnisse zu greppen.
David Ferenczy Rogožan
Die $ SHELL env. Variable zeigt auf die 'übergeordnete' Shell, wie in der POSIX-Spezifikation angegeben: SHELL Diese Variable soll einen Pfadnamen des vom Benutzer bevorzugten Befehlsspracheninterpreters darstellen. Daher ist der Wert von $ SHELL möglicherweise nicht die aktuelle Shell.
Theo
alle innerhalb awk,ps | awk '$1=='$$' { n=split($4,a,"/"); print a[n] }'
go2null
16

$SHELLmuss nicht immer die aktuelle Shell anzeigen. Es gibt nur die Standard-Shell wieder, die aufgerufen werden soll.

Um das oben Gesagte zu testen, sagen wir, es bashist die Standard-Shell, versuchen Sie es echo $SHELLund rufen Sie dann im selben Terminal eine andere Shell auf ( z. B. KornShell (ksh)) und versuchen Sie es $SHELL. In beiden Fällen wird das Ergebnis als Bash angezeigt.

Verwenden Sie Verwenden, um den Namen der aktuellen Shell abzurufen cat /proc/$$/cmdline. Und der Pfad zur ausführbaren Shell von readlink /proc/$$/exe.

sr01853
quelle
8
... vorausgesetzt du hast /proc.
Tripleee
10

ps ist die zuverlässigste Methode. Es ist nicht garantiert, dass die Umgebungsvariable SHELL festgelegt wird, und selbst wenn dies der Fall ist, kann sie leicht gefälscht werden.

ennuikiller
quelle
12
+1 $ SHELL ist die Standard-Shell für Programme, die eine erzeugen müssen. Es spiegelt nicht unbedingt die Shell wider, die gerade ausgeführt wird.
Jim Lewis
8

Ich habe einen einfachen Trick, um die aktuelle Shell zu finden. Geben Sie einfach eine zufällige Zeichenfolge ein (was kein Befehl ist). Es wird fehlschlagen und einen "nicht gefundenen" Fehler zurückgeben, aber am Anfang der Zeile wird angezeigt, um welche Shell es sich handelt:

ksh: aaaaa: not found [No such file or directory]
bash: aaaaa: command not found
user5659949
quelle
3
Nicht gut in einem Skript. echo 'aaaa' > script; chmod +x script; ./scriptgibt./script.sh: 1: aaaa: not found
schlank
6

Im Folgenden wird immer die tatsächlich verwendete Shell angegeben - es wird der Name der tatsächlich ausführbaren Datei und nicht der Shell-Name (dh ksh93anstelle von kshusw.) abgerufen. Denn /bin/shes wird die tatsächlich verwendete Shell angezeigt, dh dash.

ls -l /proc/$$/exe | sed 's%.*/%%'

Ich weiß, dass es viele gibt, die sagen, dass die lsAusgabe niemals verarbeitet werden sollte, aber wie hoch ist die Wahrscheinlichkeit, dass Sie eine Shell verwenden, die mit Sonderzeichen benannt oder in einem Verzeichnis mit Sonderzeichen abgelegt ist? Wenn dies immer noch der Fall ist, gibt es viele andere Beispiele dafür, wie man es anders macht.

Wie Toby Speight hervorhob , wäre dies ein angemessener und sauberer Weg, um dasselbe zu erreichen:

basename $(readlink /proc/$$/exe)
Vadimbog
quelle
3
Dies ist nur ein Fehler bei allen Unices, die nicht bereitstellen /proc. Nicht die ganze Welt ist eine Linux-Box.
Jens
5
Und wenn Sie sind auf Linux, würden wir es vorziehen , basename $(readlink /proc/$$/exe)zu ls+ sed+ echo.
Toby Speight
1
Dies gibt den Namen der tatsächlichen ausführbaren Datei an , nicht die tatsächliche Shell . Wenn die eigentliche Shell beispielsweise als Busybox-Applet verknüpft ist ash -> /bin/busybox, wird dies / bin / Busybox ergeben.
stepse
6

Ich habe viele verschiedene Ansätze ausprobiert und der beste für mich ist:

ps -p $$

Es funktioniert auch unter Cygwin und kann keine falsch positiven Ergebnisse als PID-Grepping erzeugen. Bei einigen Bereinigungen wird nur ein ausführbarer Name ausgegeben (unter Cygwin mit Pfad):

ps -p $$ | tail -1 | awk '{print $NF}'

Sie können eine Funktion erstellen, damit Sie sie sich nicht merken müssen:

# Print currently active shell
shell () {
  ps -p $$ | tail -1 | awk '{print $NF}'
}

... und dann einfach ausführen shell.

Es wurde unter Debian und Cygwin getestet.

David Ferenczy Rogožan
quelle
Ab meinem Setup (Cygwin | Windows 7) ist Ihre Antwort die beste und ps -p $$ | Schwanz -1 | gawk '{print $ NF}' funktioniert auch von cmd ohne $ bash. Bitte beachten Sie gawk statt awk, da awk nur mit bash funktioniert.
WebComer
@WebComer Sorry, ich bin mir nicht sicher, was du mit " funktioniert auch von cmd ohne $ bash " meinst . Auch wenn Sie von Windows - Ports haben würde ps, tailund gawk, cmd wird nicht definiert , $$wie PID es ist , so dass es auf jeden Fall kann es nicht Arbeit unter der Ebene cmd.
David Ferenczy Rogožan
Warum nicht einfach ps -p$$ -o comm=? POSIX sagt, dass die Angabe aller leeren Header den Header vollständig unterdrückt. Wir scheitern immer noch (wie alle psAntworten), wenn wir von einem direkt ausgeführten Skript (z #!/bin/sh. B. ) bezogen werden.
Toby Speight
5

Meine Variante zum Drucken des übergeordneten Prozesses:

ps -p $$ | awk '$1 == PP {print $4}' PP=$$

Führen Sie keine unnötigen Anwendungen aus, wenn AWK dies für Sie tun kann.

Matthew Stier
quelle
2
Warum ein unnötiges ausführen awk, wann ps -p "$$" -o 'comm='kann es für Sie tun?
Toby Speight
5

Es gibt viele Möglichkeiten, die Shell und ihre entsprechende Version herauszufinden. Hier sind einige, die für mich gearbeitet haben.

Einfach

  1. $> echo $ 0 (Gibt Ihnen den Programmnamen. In meinem Fall war die Ausgabe -bash .)
  2. $> $ SHELL (Dies führt Sie in die Shell und in der Eingabeaufforderung erhalten Sie den Namen und die Version der Shell. In meinem Fall bash3.2 $ .)
  3. $> echo $ SHELL (Dies gibt Ihnen einen ausführbaren Pfad. In meinem Fall / bin / bash .)
  4. $> $ SHELL --version (Hier erhalten Sie vollständige Informationen zur Shell-Software mit Lizenztyp.)

Hackischer Ansatz

$> ******* ( Geben Sie eine Reihe von zufälligen Zeichen ein und in der Ausgabe erhalten Sie den Shell-Namen. In meinem Fall -bash: Kapitel2-a-sample-isomorphic-app: Befehl nicht gefunden )

Devang Paliwal
quelle
3

Vorausgesetzt, Sie /bin/shunterstützen den POSIX-Standard und auf Ihrem System ist der lsofBefehl installiert - eine mögliche Alternative zu lsofdiesem Fall pid2path-, können Sie auch das folgende Skript verwenden (oder anpassen), das vollständige Pfade druckt:

#!/bin/sh
# cat /usr/local/bin/cursh
set -eu
pid="$$"

set -- sh bash zsh ksh ash dash csh tcsh pdksh mksh fish psh rc scsh bournesh wish Wish login

unset echo env sed ps lsof awk getconf

# getconf _POSIX_VERSION  # reliable test for availability of POSIX system?
PATH="`PATH=/usr/bin:/bin:/usr/sbin:/sbin getconf PATH`"
[ $? -ne 0 ] && { echo "'getconf PATH' failed"; exit 1; }
export PATH

cmd="lsof"
env -i PATH="${PATH}" type "$cmd" 1>/dev/null 2>&1 || { echo "$cmd not found"; exit 1; }

awkstr="`echo "$@" | sed 's/\([^ ]\{1,\}\)/|\/\1/g; s/ /$/g' | sed 's/^|//; s/$/$/'`"

ppid="`env -i PATH="${PATH}" ps -p $pid -o ppid=`"
[ "${ppid}"X = ""X ] && { echo "no ppid found"; exit 1; }

lsofstr="`lsof -p $ppid`" || 
   { printf "%s\n" "lsof failed" "try: sudo lsof -p \`ps -p \$\$ -o ppid=\`"; exit 1; }

printf "%s\n" "${lsofstr}" | 
   LC_ALL=C awk -v var="${awkstr}" '$NF ~ var {print $NF}'
carlo
quelle
1
Das funktioniert bei Fischen! Aber für mich schlägt Bash aufgrund der -iOption (-> Umgebung ignorieren) envin der Zeile fehl , in der Sie prüfen lsof, ob sie verfügbar ist. es schlägt fehl mit: env -i PATH="${PATH}" type lsof->env: ‘type’: No such file or directory
hoijui
2

Wenn Sie nur überprüfen möchten, ob Sie (eine bestimmte Version von) Bash ausführen, verwenden Sie am besten die $BASH_VERSINFO Array-Variable. Als (schreibgeschützte) Array-Variable kann sie nicht in der Umgebung festgelegt werden, sodass Sie sicher sein können, dass sie (wenn überhaupt) von der aktuellen Shell stammt.

Da Bash beim Aufrufen als ein anderes Verhalten aufweist sh, müssen Sie auch überprüfen, ob die $BASHUmgebungsvariable mit endet /bash.

In einem Skript, das ich geschrieben habe und das Funktionsnamen mit -(nicht Unterstrich) verwendet und von assoziativen Arrays abhängt (hinzugefügt in Bash 4), habe ich die folgende Überprüfung der Integrität (mit hilfreicher Benutzerfehlermeldung):

case `eval 'echo $BASH@${BASH_VERSINFO[0]}' 2>/dev/null` in
    */bash@[456789])
        # Claims bash version 4+, check for func-names and associative arrays
        if ! eval "declare -A _ARRAY && func-name() { :; }" 2>/dev/null; then
            echo >&2 "bash $BASH_VERSION is not supported (not really bash?)"
            exit 1
        fi
        ;;
    */bash@[123])
        echo >&2 "bash $BASH_VERSION is not supported (version 4+ required)"
        exit 1
        ;;
    *)
        echo >&2 "This script requires BASH (version 4+) - not regular sh"
        echo >&2 "Re-run as \"bash $CMD\" for proper operation"
        exit 1
        ;;
esac

Sie könnten im ersten Fall die etwas paranoide Funktionsprüfung für Funktionen weglassen und einfach davon ausgehen, dass zukünftige Bash-Versionen kompatibel sind.

Alex Dupuy
quelle
2

Keine der Antworten funktionierte mit fishShell (es hat nicht die Variablen $$oder $0).

Dies funktioniert für mich (getestet auf sh, bash, fish, ksh, csh, true, tcsh, und zsh; openSUSE 13.2):

ps | tail -n 4 | sed -E '2,$d;s/.* (.*)/\1/'

Dieser Befehl gibt eine Zeichenfolge wie aus bash. Hier bin ich nur mit ps, tailund sed(ohne GNU extesions, versuchen Sie fügen --posixes zu überprüfen). Dies sind alles Standard-POSIX-Befehle. Ich bin sicher, tailkann entfernt werden, aber mein sedFu ist nicht stark genug, um dies zu tun.

Es scheint mir, dass diese Lösung nicht sehr portabel ist, da sie unter OS X nicht funktioniert. :(

rominf
quelle
Ich bekomme sed: invalid option -- 'E'auf Bash 3.2.51 und tcsh 6.15.00
craq
2

Meine Lösung:

ps -o command | grep -v -e "\<ps\>" -e grep -e tail | tail -1

Dies sollte auf verschiedenen Plattformen und Shells portierbar sein. Es wird pswie andere Lösungen verwendet, ist jedoch nicht auf sedoder angewiesen awkund filtert Müll aus den Rohrleitungen und sich psselbst heraus, sodass die Shell immer der letzte Eintrag sein sollte. Auf diese Weise müssen wir uns nicht auf nicht tragbare PID-Variablen verlassen oder die richtigen Zeilen und Spalten auswählen.

Ich habe unter Debian und macOS mit Bash, Z shell ( zsh) und fish getestet (was mit den meisten dieser Lösungen nicht funktioniert, ohne den Ausdruck speziell für fish zu ändern, da eine andere PID-Variable verwendet wird).

Wickles
quelle
1
echo $$ # Gives the Parent Process ID 
ps -ef | grep $$ | awk '{print $8}' # Use the PID to see what the process is.

Von Woher wissen Sie , was Ihre aktuelle Shell ist? .

Moisei
quelle
3
Es ist nicht der übergeordnete Prozess - es ist der aktuelle Prozess.
Bis auf weiteres angehalten.
7
Die Verwendung grep $$ist unzuverlässig. ps -ef | awk -v pid=$$ '$2==pid { print $8 }'ist besser, aber warum nicht einfach verwenden ps -p $$?
Musiphil
1

Unter Mac OS X (und FreeBSD):

ps -p $$ -axco command | sed -n '$p' 
zaga
quelle
2
Versuchte dies während der Verwendung zsh, und es gab mir -bash.
user137369
Auf meinem System (jetzt), getestet mit Bash und Dash, diese Rückkehr mutt...: -b
F. Hauri
1

Das Abrufen der PID von der Ausgabe von "ps" ist nicht erforderlich, da Sie die entsprechende Befehlszeile für jede PID aus der Verzeichnisstruktur / proc lesen können:

echo $(cat /proc/$$/cmdline)

Das ist jedoch vielleicht nicht besser als nur:

echo $0

Wenn Sie eine andere Shell ausführen möchten, als der Name angibt, sollten Sie die Version unter dem zuvor angegebenen Namen von der Shell anfordern:

<some_shell> --version

sh scheint mit Exit-Code 2 zu scheitern, während andere etwas Nützliches geben (aber ich kann nicht alle überprüfen, da ich sie nicht habe):

$ sh --version
sh: 0: Illegal option --
echo $?
2
ajaaskel
quelle
1

Dies ist keine sehr saubere Lösung, aber sie macht, was Sie wollen.

# MUST BE SOURCED..
getshell() {
    local shell="`ps -p $$ | tail -1 | awk '{print $4}'`"

    shells_array=(
    # It is important that the shells are listed in descending order of their name length.
        pdksh
        bash dash mksh
        zsh ksh
        sh
    )

    local suited=false
    for i in ${shells_array[*]}; do
        if ! [ -z `printf $shell | grep $i` ] && ! $suited; then
            shell=$i
            suited=true
        fi
    done

    echo $shell
}
getshell

Jetzt können Sie verwenden $(getshell) --version.

Dies funktioniert jedoch nur bei KornShell- ähnlichen Shells (ksh).

theoden8
quelle
1
"Dies funktioniert jedoch nur bei ksh-ähnlichen Muscheln." Wollen Sie damit sagen, dass ich die Shell überprüfen muss, bevor ich sie ausführen kann ? Hmm ...
jpaugh
@jpaugh, Listen müssen die von der Shell unterstützt diesen Code Sourcing, die nicht der Fall ist dash, yashusw. Normalerweise , wenn Sie mit bash, zsh, ksh, was auch immer - Sie sollten über solche Dinge nicht.
Theoden8
Sie zählen Bash also als "ksh-like"? Ich habs. Das macht mehr Sinn
jpaugh
@jpaugh, nun, das habe ich gemeint, weil kshdie Funktionen meistens eine Teilmenge der bashFunktionen sind (habe dies jedoch nicht gründlich überprüft).
Theoden8
1

Gehen Sie folgendermaßen vor, um festzustellen, ob Ihre Shell Dash / Bash verwendet.

ls –la /bin/sh::

  • Wenn das Ergebnis /bin/sh -> /bin/bash==> ist, verwendet Ihre Shell Bash.

  • Wenn das Ergebnis /bin/sh ->/bin/dash==> ist, verwendet Ihre Shell Dash.

Wenn Sie von Bash zu Dash oder umgekehrt wechseln möchten, verwenden Sie den folgenden Code:

ln -s /bin/bash /bin/sh (Shell in Bash ändern)

Hinweis : Wenn der obige Befehl zu einem Fehler führt, der besagt, dass / bin / sh bereits vorhanden ist, entfernen Sie / bin / sh und versuchen Sie es erneut.

Shiva
quelle
0

Und ich habe mir das ausgedacht

sed 's/.*SHELL=//; s/[[:upper:]].*//' /proc/$$/environ
Ivan
quelle
Dies funktioniert nur unter Linux ! Weder MacOS noch BSD !!
F. Hauri
-1

Bitte benutzen Sie den folgenden Befehl:

ps -p $$ | tail -1 | awk '{print $4}'
Ranjithkumar T.
quelle
Das erste ist Unsinn, echo $SHELLmacht das , was Sie versuchen, und macht es gut. Die zweite ist ebenfalls nicht gut, da die $SHELLUmgebungsvariable die Standard-Shell für einen aktuellen Benutzer enthält, keine aktuell ausgeführte Shell. Wenn ich zum Beispiel bashals Standard-Shell festgelegt habe, führen Sie zshund aus echo $SHELL, es wird gedruckt bash.
David Ferenczy Rogožan
Sie haben Recht, Dawid Ferenczy. Wir können den Befehl ps verwenden, um die aktuelle Shell zu bestimmen. [# ps -p $$ | Schwanz -1 | awk '{print $ 4}'].
Ranjithkumar T
echo $SHELLkann Müll sein: ~ $ echo $SHELL /bin/zsh ~ $ bash bash-4.3$ echo $SHELL /bin/zsh bash-4.3$
SalzwasserC
-2

Dieser funktioniert gut unter Red Hat Linux (RHEL), MacOS, BSD und einigen AIXs :

ps -T $$ | awk 'NR==2{print $NF}' 

alternativ sollte das folgende auch funktionieren, wenn pstree verfügbar ist:

pstree | egrep $$ | awk 'NR==2{print $NF}'
martin zahrubsky
quelle