Jak zkontrolovat, co Shell používám v terminálu? Co je to prostředí, které používám v MacOSu?
Několik způsobů, od nejspolehlivějších (a nejtěžších "těžkých"):
ps -p$$ -ocmd=
. (V systému Solaris to může být místo fname
místo cmd
. V OSX a BSD by měl být command
místo cmd
.)$BASH_VERSION
, $ZSH_VERSION
a další proměnné specifické pro Shell.$Shell
; Toto je poslední možnost, protože určuje váš výchozí Shell a ne nutně aktuální Shell.Zjistil jsem, že následující práce ve čtyřech skořápkách, které jsem nainstaloval do svého systému (bash, dash, zsh, csh):
$ ps -p $$
Následující práce na zsh, bash a dash, ale ne na csh:
$ echo $0
Jak se otázka ptá na použité Shell a nemluví o možných argumentech, které mu byly předány, zde je způsob, jak se jim vyhnout:
$ ps -o comm= -p $$
ksh93
Poznámka o některých lehčích implementacích (telefony Android, busybox atd.): ps
nemá vždy podporu pro přepínač -p
, Ale vyhledávání můžete provést příkazem, jako je ps | grep "^$$ "
. (Tento grep
regex jedinečně identifikuje PID, takže nebudou existovat žádné falešné pozitivy.
Existují dva opravdu jednoduché způsoby:
Pomocí příkazu ps :
ps -o comm= $$
nebo
ps -h -o comm -p $$
kde:
-h
nebo dokončení všech možností pomocí =
za nezobrazení záhlaví.-o comm
pro zobrazení pouze základního názvu procesu (bash
místo /bin/bash
).-p <PID>
seznam zpracovat pouze s dodaným seznamem formulářů PID.Používání /proc systému informací o pseudo souborech:
cat /proc/$$/comm
Tato možnost se chová přesně jako výše uvedený příkaz ps
.
nebo
readlink /proc/$$/exe
Tento /proc/PID/exe
odkazy na prováděný soubor, který by v tomto případě ukazoval na/bin/bash,/bin/ksh atd.
Pro získání pouze názvu skořápky můžete použít
basename $(readlink /proc/$$/exe)
Toto je jediná možnost, která bude vždy dávat stejný výsledek, i když jste ve skriptu, zdrojovém kódu nebo terminálu, jako odkazy na používaný binární interpret Shell.
Varování Musíte si uvědomit, že to ukáže konečný binární, takže ksh může být spojen s ksh93 nebo sh k bash.
Použití /proc
je opravdu užitečné pomocí /proc/self
, která odkazuje na PID aktuálního příkazu.
Kombinace všech ostatních odpovědí, kompatibilních s Mac (comm), Solaris (fname) a Linux (cmd):
ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1
Pokud ji máte uloženou ve svých proměnných prostředí, můžete použít následující:
echo $Shell
Pid běžícího Shell je dán var $$ (ve většině skořápek).
whichsh="`ps -o pid,args| awk '$1=='"$$"'{print $2}'`"
echo "$whichsh"
Používání backticků pro práci jsh (Heirlomm Shell).
V mnoha skořápkách přímý test ps -o args= -p $$
funguje, ale busybox ash
selže v tom (vyřešeno).
Kontrola, že $1
se musí rovnat $$
odstraní většinu falešných pozitiv.
Poslední ;:
slouží k udržení prostředí Shell pro ksh a zsh.
Testy na více systémech pomohou. Pokud to pro vás nefunguje, napište komentář.
Nefunguje v typu skořápek csh
.
Nastavil jsem $MYSHELL
pro budoucí testy v mé Shell-agnostice ~/.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
Sekce tcsh
se pravděpodobně nebude rozumně převádět do skriptu ve stylu POSIX, protože je tak radikálně odlišný (tedy varování a pětisekundová pauza). (Pro jednoho, csh
- skořápky stylu nemohou dělat 2>/dev/null
nebo >&2
, jak je uvedeno ve slavném Csh Programming zváží škodlivé výkřik.)