Jak sprawdzić, jakiej powłoki używam w terminalu? Jakiej powłoki używam w MacOS?
echo #SHELL
to nie do końca. Zobacz # 3 w odpowiedzi autora geekozaura .
xterm -e /bin/cat
ale nie podoba mi się wywołanie /bin/cat
powłoki.
Jak sprawdzić, jakiej powłoki używam w terminalu? Jakiej powłoki używam w MacOS?
echo #SHELL
to nie do końca. Zobacz # 3 w odpowiedzi autora geekozaura .
xterm -e /bin/cat
ale nie podoba mi się wywołanie /bin/cat
powłoki.
Odpowiedzi:
Kilka sposobów, od najbardziej do najmniej niezawodnego (i od „najmniej ciężkiego”):
ps -p$$ -ocmd=
. (W Solarisie może to być konieczne fname
zamiast cmd
. W OSX i BSD powinno być command
zamiast cmd
.)$BASH_VERSION
, $ZSH_VERSION
i inne zmienne powłoki specyficzne.$SHELL
; jest to ostateczność, ponieważ określa domyślną powłokę, a niekoniecznie bieżącą powłokę.$0
też powinieneś wspomnieć ?
$0
ponieważ jest to bardziej skomplikowane: (1) może to być tylko basename, (2) może mieć z przodu „-”, aby oznaczyć go jako powłokę logowania.
ps -p$$ -ocmd=""
jest ładniejszy :-)
$0
nadal wydaje się bardziej przydatny niż $SHELL
: nie zgadzasz się? Zawsze można go przepuścić, sed
aby usunąć „-”.
tcsh
, $tcsh
a $version
zostanie 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.
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
%self
można stosować zamiast$$
Uwaga na temat niektórych lżejszych implementacji (telefony z Androidem, busybox itp.): ps
Nie zawsze obsługuje -p
przełącznik, ale można przeprowadzić wyszukiwanie za pomocą polecenia podobnego do ps | grep "^$$ "
. (Ta grep
regex jednoznacznie identyfikuje PID, więc nie będzie żadnych fałszywych trafień.
ps | grep $$
nadal może dawać fałszywe alarmy, jeśli na przykład twój obecny proces jest 1234
i istnieje proces 12345
.
Istnieją dwa naprawdę proste sposoby:
Za pomocą polecenia ps :
ps -o comm= $$
lub
ps -h -o comm -p $$
gdzie:
-h
lub kończenie wszystkich opcji =
za nie pokazywanie żadnego nagłówka.-o comm
do pokazywania tylko basename procesu ( bash
zamiast /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 ps
powyż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 /proc
jest naprawdę przydatne poprzez /proc/self
, który prowadzi do PID bieżącego polecenia.
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
csh
i tcsh
daje miAmbiguous output redirect.
Jeśli masz to zapisane w zmiennych środowiskowych, możesz użyć:
echo $SHELL
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 ash
nie powiedzie (rozwiązany).
Kontrola, która $1
musi 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 csh
typie powłok.
/usr/lib/dyld
, jedną dla /private/var/db/dyld/dyld_shared_cache_x86_64
.
Przygotowałem się $MYSHELL
do 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
tcsh
Sekcja 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, csh
pociski w stylu nie mogą tego zrobić 2>/dev/null
lub >&2
, jak zauważono w słynnym Programie Csh Program uważany za szkodliwy ).