Jak sprawdzić, jakiej powłoki używam w terminalu?

69

Jak sprawdzić, jakiej powłoki używam w terminalu? Jakiej powłoki używam w MacOS?

użytkownik5837
źródło
2
@xenoterracide: przynajmniej unix.stackexchange.com/questions/3645/… . odpowiedź geekozaura jest bardziej kompletna, więc głosowałem za zamknięciem wcześniejszego pytania.
Gilles
1
echo $ SHELL, nie?
innocent-world
@ innocent-world Nie, echo #SHELLto nie do końca. Zobacz # 3 w odpowiedzi autora geekozaura .
Basil Bourque,
Nie jestem pewien, czy „shell” ma dobrze zdefiniowane znaczenie. Na przykład możesz uruchomić, xterm -e /bin/cat ale nie podoba mi się wywołanie /bin/catpowłoki.
Basile Starynkevitch
Również niektóre powłoki (jak scsh ) nie używają powłoki POSIX jak składnia.
Basile Starynkevitch

Odpowiedzi:

71

Kilka sposobów, od najbardziej do najmniej niezawodnego (i od „najmniej ciężkiego”):

  1. ps -p$$ -ocmd=. (W Solarisie może to być konieczne fnamezamiast cmd. W OSX i BSD powinno być commandzamiast cmd.)
  2. Sprawdź, czy nie $BASH_VERSION, $ZSH_VERSIONi inne zmienne powłoki specyficzne.
  3. Sprawdź $SHELL; jest to ostateczność, ponieważ określa domyślną powłokę, a niekoniecznie bieżącą powłokę.
geekozaur
źródło
4
Czy ty $0też powinieneś wspomnieć ?
Mikel
Nie podoba mi się, $0ponieważ jest to bardziej skomplikowane: (1) może to być tylko basename, (2) może mieć z przodu „-”, aby oznaczyć go jako powłokę logowania.
geekozaur
ps -p$$ -ocmd=""jest ładniejszy :-)
asoundmove 18.03.11
1
@geekosaur: może tak, ale $0nadal wydaje się bardziej przydatny niż $SHELL: nie zgadzasz się? Zawsze można go przepuścić, sedaby usunąć „-”.
iconoclast
2
Jeśli używasz tcsh, $tcsha $versionzostanie ustawiona. Są to zmienne powłoki, a nie zmienne środowiskowe. Jeśli używasz wersji innej niż tcsh csh, nie sądzę, aby istniały jakieś charakterystyczne zmienne. Oczywiście składnia używana do sprawdzania zmiennych różni się między csh / tcsh z jednej strony, a sh / ksh / bash / zsh z drugiej.
Keith Thompson
41

Przekonałem się, że następujące działania działają w czterech powłokach, które zainstalowałem w moim systemie (bash, dash, zsh, csh):

$ ps -p $$

Następujące działa na Zsh, Bash i Dash, ale nie na csh:

$ echo $0
Steven D.
źródło
2
Nie działa również na ryby.
Ron E
Myślę, że odpowiedź @ jiliagre byłaby prawdopodobnie użyta dzisiaj. Na rybach %selfmożna stosować zamiast$$
Steven D
8

Ponieważ pytanie dotyczy użytej powłoki i nie mówi o potencjalnych argumentach, które zostały do ​​niej przekazane, oto sposób na ich uniknięcie:

$ ps -o comm= -p $$
ksh93 
jlliagre
źródło
6

Uwaga na temat niektórych lżejszych implementacji (telefony z Androidem, busybox itp.): psNie zawsze obsługuje -pprzełącznik, ale można przeprowadzić wyszukiwanie za pomocą polecenia podobnego do ps | grep "^$$ ". (Ta grepregex jednoznacznie identyfikuje PID, więc nie będzie żadnych fałszywych trafień.

palswim
źródło
7
ps | grep $$nadal może dawać fałszywe alarmy, jeśli na przykład twój obecny proces jest 1234i istnieje proces 12345.
Keith Thompson
4

Istnieją dwa naprawdę proste sposoby:

  • Za pomocą polecenia ps :

    ps -o comm= $$

    lub

    ps -h -o comm -p $$

    gdzie:

    • -hlub kończenie wszystkich opcji =za nie pokazywanie żadnego nagłówka.
    • -o commdo pokazywania tylko basename procesu ( bashzamiast /bin/bash).
    • -p <PID> przetwarzaj tylko listę z dostarczoną listą formularza PID.
  • Korzystanie z systemu pseudo-plików informacji o procesie / proc :

    cat /proc/$$/comm

    Ta opcja działa dokładnie tak, jak pspowyższe polecenie.

    lub

    readlink /proc/$$/exe

    To /proc/PID/exełącze do wykonywanego pliku, który w tym przypadku wskazywałby na / bin / bash, / bin / ksh itp.

    Aby uzyskać tylko nazwę powłoki, której możesz użyć

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

    Jest to jedyna opcja, która zawsze daje taki sam wynik, nawet jeśli znajdujesz się w skrypcie, kodzie źródłowym lub terminalu, jako linki do pliku binarnego używanego interpretera powłoki.

    Ostrzeżenie Musisz mieć świadomość, że pokaże to ostateczny plik binarny, więc ksh może być powiązany z ksh93 lub sh, aby bash.

Użycie /procjest naprawdę przydatne poprzez /proc/self, który prowadzi do PID bieżącego polecenia.

David Goitia
źródło
3

Mieszanka wszystkich pozostałych odpowiedzi, zgodna z Mac (comm), Solaris (fname) i Linux (cmd):

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1
Sebastian
źródło
to daje mi nazwę mojego bieżącego katalogu; również pod cshi tcshdaje miAmbiguous output redirect.
iconoclast
2

Jeśli masz to zapisane w zmiennych środowiskowych, możesz użyć:

echo $SHELL
jasonleonhard
źródło
Najprawdopodobniej zwróci to nazwę pliku wykonywalnego powłoki powłoki logowania. Nie jest jednak pewne, czy powłoka logowania jest aktualnie uruchomiona.
Kusalananda
1

Pid działającej powłoki jest podany przez zmienną var $$ (w większości powłok).

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

Korzystanie z backticków do działania jsh (powłoki Heirlomma).

W wielu powłokach bezpośredni test ps -o args= -p $$działa, ale się busybox ashnie powiedzie (rozwiązany).

Kontrola, która $1musi być równa, $$usuwa większość fałszywych trafień.

Te ostatnie ;:służą do utrzymania powłoki działającej dla ksh i zsh.

Pomogą w tym testy na większej liczbie systemów, prosimy o komentarz, jeśli to nie zadziała.

Nie działa w cshtypie powłok.


źródło
Na OS / X, w moich testach, dostaję co najmniej 3 linie, jedną dla powłoki, jedną dla /usr/lib/dyld, jedną dla /private/var/db/dyld/dyld_shared_cache_x86_64.
Stéphane Chazelas,
Tak, teraz wybiera tylko wpisy w / bin i / usr / bin
Stéphane Chazelas
@ StéphaneChazelas Może teraz jest lepiej?
0

Przygotowałem się $MYSHELLdo przyszłych testów w mojej agnostyce ~/.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

tcshSekcja jest prawdopodobnie nierozsądne toczyć do skryptu POSIX stylu, ponieważ jest to tak radykalnie różny (stąd ostrzeżenie pięć sekundowa przerwa). (Po pierwsze, cshpociski w stylu nie mogą tego zrobić 2>/dev/nulllub >&2, jak zauważono w słynnym Programie Csh Program uważany za szkodliwy ).

Adam Katz
źródło
-1

Możesz po prostu użyć echo $0polecenia, aby sprawdzić, której powłoki używasz i <name_of_the_shell> --versionsprawdzić jej wersję. (np. bash --version).

Sachin C.
źródło
Steven D już o tym wspomniał
:)