@xenoterracide: przynajmniej unix.stackexchange.com/questions/3645/… . odpowiedź geekozaura jest bardziej kompletna, więc głosowałem za zamknięciem wcześniejszego pytania.
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”):
ps -p$$ -ocmd=. (W Solarisie może to być konieczne fnamezamiast cmd. W OSX i BSD powinno być commandzamiast cmd.)
Sprawdź, czy nie $BASH_VERSION, $ZSH_VERSIONi inne zmienne powłoki specyficzne.
Sprawdź $SHELL; jest to ostateczność, ponieważ określa domyślną powłokę, a niekoniecznie bieżącą powłokę.
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:
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ń.
-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.
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).
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# verifyif[!-x "$MYSHELL"];then
MYSHELL=`command -v "$(ps $$ |awk 'NR == 2 { print $NF }')"`[-x "$MYSHELL"]|| MYSHELL="${SHELL:-/bin/sh}"# default if verify failsfi
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 ).
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).
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ć koniecznefname
zamiastcmd
. W OSX i BSD powinno byćcommand
zamiastcmd
.)$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ę.źródło
$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ż tcshcsh
, 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):
Następujące działa na Zsh, Bash i Dash, ale nie na csh:
źródło
%self
można stosować zamiast$$
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:
źródło
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 dops | grep "^$$ "
. (Tagrep
regex jednoznacznie identyfikuje PID, więc nie będzie żadnych fałszywych trafień.źródło
ps | grep $$
nadal może dawać fałszywe alarmy, jeśli na przykład twój obecny proces jest1234
i istnieje proces12345
.Istnieją dwa naprawdę proste sposoby:
Za pomocą polecenia ps :
lub
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 :
Ta opcja działa dokładnie tak, jak
ps
powyższe polecenie.lub
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ć
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.źródło
Mieszanka wszystkich pozostałych odpowiedzi, zgodna z Mac (comm), Solaris (fname) i Linux (cmd):
źródło
csh
itcsh
daje miAmbiguous output redirect.
Jeśli masz to zapisane w zmiennych środowiskowych, możesz użyć:
źródło
Pid działającej powłoki jest podany przez zmienną var $$ (w większości powłok).
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.źródło
/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
: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 ).źródło
Możesz po prostu użyć
echo $0
polecenia, aby sprawdzić, której powłoki używasz i<name_of_the_shell> --version
sprawdzić jej wersję. (np.bash --version
).źródło
To też działa:
źródło