Bagaimana cara menguji cangkang apa yang saya gunakan di terminal?

69

Bagaimana cara memeriksa cangkang apa yang saya gunakan di terminal? Apa shell yang saya gunakan di MacOS?

pengguna5837
sumber
2
@xenoterracide: setidaknya unix.stackexchange.com/questions/3645/… . Jawaban geekosaur lebih lengkap, jadi saya memilih untuk menutup pertanyaan sebelumnya.
Gilles 'SANGAT berhenti menjadi jahat'
1
echo $ SHELL, bukan?
dunia tidak bersalah
@ dunia tidak bersalah Tidak, echo #SHELLtidak cukup itu. Lihat # 3 di Jawaban oleh geekosaur .
Basil Bourque
Saya tidak begitu yakin bahwa "shell" memiliki arti yang jelas. Misalnya, Anda mungkin lari xterm -e /bin/cat tetapi saya tidak senang memanggil /bin/catshell.
Basile Starynkevitch
Juga beberapa shell (seperti scsh ) tidak menggunakan shell POSIX seperti sintaks.
Basile Starynkevitch

Jawaban:

71

Beberapa cara, dari yang paling dapat diandalkan (dan "paling berat"):

  1. ps -p$$ -ocmd=. (Pada Solaris, ini mungkin harus sebagai fnameganti cmd. Pada OSX dan pada BSD seharusnya commandbukan cmd.)
  2. Periksa $BASH_VERSION, $ZSH_VERSION, dan variabel shell-spesifik lainnya.
  3. Periksa $SHELL; ini adalah pilihan terakhir, karena menentukan shell default Anda dan belum tentu shell saat ini .
geekosaurus
sumber
4
Haruskah Anda menyebutkannya $0juga?
Mikel
Saya tidak suka $0karena ini lebih rumit: (1) mungkin hanya nama dasarnya, (2) mungkin ada '-' di bagian depan untuk menetapkannya sebagai shell login.
geekosaur
ps -p$$ -ocmd=""lebih cantik :-)
asoundmove
1
@geekosaur: mungkin begitu, tetapi $0masih tampak lebih bermanfaat daripada $SHELL: tidakkah Anda setuju? Anda selalu dapat menyalurkan melalui seduntuk menghapus '-'.
iconoclast
2
Jika Anda menjalankan tcsh, $tcshdan $versionakan diatur. Ini adalah variabel shell, bukan variabel lingkungan. Jika Anda menjalankan versi non-tcsh csh, saya tidak berpikir ada variabel khusus. Dan tentu saja sintaks yang digunakan untuk memeriksa variabel berbeda antara csh / tcsh di satu sisi, dan sh / ksh / bash / zsh di sisi lain.
Keith Thompson
41

Saya telah menemukan bahwa yang berikut ini berfungsi pada empat shell yang telah saya instal pada sistem saya (bash, dash, zsh, csh):

$ ps -p $$

Berikut ini berfungsi pada zsh, bash, dan dash, tetapi tidak pada csh:

$ echo $0
Steven D
sumber
2
Juga tidak berfungsi pada ikan.
Ron E
Saya pikir jawaban @ jiliagre mungkin akan saya gunakan hari ini. Pada ikan %selfdapat digunakan sebagai pengganti$$
Steven D
8

Karena pertanyaannya menanyakan shell yang digunakan dan tidak berbicara tentang argumen potensial yang diteruskan kepadanya, berikut adalah cara yang tidak menunjukkannya:

$ ps -o comm= -p $$
ksh93 
Jlliagre
sumber
6

Catatan tentang beberapa implementasi yang lebih ringan (ponsel Android, busybox, dll.): psTidak selalu memiliki dukungan untuk -pperalihan, tetapi Anda dapat menyelesaikan pencarian dengan perintah seperti ps | grep "^$$ ". ( grepRegex ini akan secara unik mengidentifikasi PID, sehingga tidak akan ada kesalahan positif.

palswim
sumber
7
ps | grep $$masih dapat memberikan hasil positif yang salah jika, misalnya, proses Anda saat ini 1234dan ada proses 12345.
Keith Thompson
4

Ada dua cara yang sangat sederhana:

  • Menggunakan perintah ps :

    ps -o comm= $$

    atau

    ps -h -o comm -p $$

    dimana:

    • -hatau menyelesaikan semua opsi dengan =untuk tidak menampilkan header apa pun.
    • -o communtuk hanya menampilkan nama proses ( bashbukan /bin/bash).
    • -p <PID> daftar hanya proses dengan daftar formulir PID yang disediakan.
  • Menggunakan sistem pseudo-file informasi proses / proc :

    cat /proc/$$/comm

    Opsi ini berlaku persis seperti psperintah di atas.

    atau

    readlink /proc/$$/exe

    /proc/PID/exeTautan ini ke file yang sedang dieksekusi, yang dalam hal ini akan menunjuk ke / bin / bash, / bin / ksh, dll.

    Untuk mendapatkan hanya nama shell yang bisa Anda gunakan

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

    Ini adalah satu-satunya opsi yang akan selalu memberikan hasil yang sama bahkan jika Anda menggunakan skrip, kode sumber, atau terminal, sebagai tautan ke biner dari penerjemah shell yang digunakan.

    Peringatan Anda harus menyadari bahwa ini akan menampilkan biner utama, jadi ksh mungkin ditautkan ke ksh93 atau sh to bash.

Penggunaan /procsangat berguna melalui /proc/self, yang menghubungkan ke PID dari perintah saat ini.

David Goitia
sumber
3

Gabungan dari semua jawaban lain, kompatibel dengan Mac (comm), Solaris (fname) dan Linux (cmd):

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1
sebastien
sumber
ini memberi saya nama direktori saya saat ini; juga, di bawah cshdan tcshitu memberi sayaAmbiguous output redirect.
iconoclast
2

Jika Anda menyimpannya di variabel lingkungan Anda, Anda dapat menggunakan yang berikut:

echo $SHELL
jasonleonhard
sumber
Itu kemungkinan besar akan mengembalikan pathname dari shell yang dapat dieksekusi dari shell login Anda. Tidak yakin shell login adalah apa yang sedang Anda jalankan.
Kusalananda
1

Pid dari shell yang berjalan diberikan oleh var $$ (dalam kebanyakan shell).

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

Menggunakan backticks untuk membuat jsh (Heirlomm shell) berfungsi.

Dalam banyak kerang tes langsung ps -o args= -p $$bekerja, tetapi busybox ashgagal itu (dipecahkan).

Cek yang $1harus sama untuk $$menghilangkan sebagian besar kesalahan positif.

Yang terakhir ;:digunakan untuk menjaga agar shell tetap berjalan untuk ksh dan zsh.

Tes pada lebih banyak sistem akan membantu, tolong beri komentar jika itu tidak berhasil untuk Anda.

Tidak bekerja dalam cshjenis kerang.


sumber
Pada OS / X, dalam pengujian saya, saya mendapatkan setidaknya 3 baris, satu untuk shell, satu untuk /usr/lib/dyld, satu untuk /private/var/db/dyld/dyld_shared_cache_x86_64.
Stéphane Chazelas
Ya, sekarang hanya memilih entri di / bin dan / usr / bin
Stéphane Chazelas
@ StéphaneChazelas Mungkin lebih baik sekarang?
0

Saya menetapkan $MYSHELLuntuk tes masa depan di shell-agnostik saya ~/.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

The tcshBagian kemungkinan tidak bijaksana untuk menggulung menjadi script POSIX-gaya karena begitu berbeda secara radikal (dengan demikian peringatan dan lima jeda kedua). (Untuk satu, cshkerang-gaya tidak dapat melakukan 2>/dev/nullatau >&2, seperti dicatat dalam kata-kata Csh Programming terkenal Dianggap Berbahaya .)

Adam Katz
sumber
-1

Anda cukup menggunakan echo $0perintah untuk memeriksa shell mana yang Anda gunakan dan <name_of_the_shell> --versionuntuk memeriksa versi shell. (mis. bash --version).

Sachin C
sumber
Steven D sudah menyebutkannya
:)
-5

Ini juga berfungsi:

env | grep SHELL
Niko
sumber
3
Atau tidak. Lihat poin 3. dalam jawaban geekosaur .
manatwork