Sesuai pengetahuan saya, untuk menentukan shell saat ini kami gunakan echo $0
dalam shell. Sebaliknya saya ingin skrip saya memeriksa shell mana yang sedang berjalan. Jadi, saya mencoba mencetak $0
skrip dan mengembalikan nama skrip sebagaimana mestinya. Jadi, pertanyaan saya adalah bagaimana saya bisa menemukan di mana shell saya menjalankan skrip saat runtime?
22
echo $0
bukan pilihan di sini, karena skrip akan berjalan pada banyak mesin yang berbeda di mana hal pertama yang perlu saya periksa adalah shell.#! /bin/sh -
di bagian atas, itu akan berjalansh
. Maksud Anda varian apash
itu?Jawaban:
Di linux Anda bisa menggunakan
/proc/PID/exe
.Contoh:
sumber
/bin/sed -r -e 's/\x0.*//' /proc/$$/cmdline
memberikan zsh atau ksh sebagai gantinya. (Itu akan menjadi $ 0 jika shell tidak secara ajaib memperbaiki ini untuk memberikan nama skrip sebagai gantinya)./proc
adalah jelek dan tidak dapat diangkut karena mendapat./proc
bukan 'jelek'./proc
seringkali merupakan solusi yang sangat elegan. Unportable ya, tetapi karena ada sesuatu yang unportable tidak membuatnya jelek./proc
jelek karena file di dalamnya mungkin datang dan pergi atas keinginan pengembang dan isi file cenderung berubah tanpa pemberitahuan, menyebabkan rasa sakit yang tak ada habisnya karena bitrot dan memindahkan format file target.Mungkin bukan yang Anda minta, tetapi ini harus bekerja sampai taraf tertentu untuk mengidentifikasi penerjemah yang saat ini menafsirkannya untuk beberapa seperti Thompson (osh), Bourne, Bourne-again (bash), Korn (ksh88, ksh93, pdksh, mksh ), zsh, Biasa Sesuai Kebijakan (posh), Yet Another (yash), rc, akanga, es shells, wish, tclsh, mengharapkan, perl, python, ruby, php, JavaScript (setidaknya nodejs, SpiderMonkey shell, dan JSPL) , MS / Wine cmd.exe, command.com (MSDOS, FreeDOS ...).
Saya memposting versi awal skrip which_interpreter sekitar tahun 2004 di usenet. Sven Mascheck memiliki skrip (mungkin lebih bermanfaat bagi Anda) yang disebut whatshell yang berfokus pada pengidentifikasian kerang mirip Bourne. Anda juga dapat menemukan versi gabungan dari dua skrip kami di sana .
sumber
print
menjadi fungsi.bash 3.2.53(1)-release
sebagai penerjemah yang menerjemahkannya.Ini adalah apa yang saya gunakan di profil saya. Untuk memeriksa berbagai shell pada sistem saya bekerja. Itu tidak membuat perbedaan yang baik antara ksh88 dan ksh93, tetapi tidak pernah mengecewakan saya.
Perhatikan bahwa itu tidak memerlukan garpu atau pipa tunggal.
sumber
ksh93
dimiliki$KSH_VERSION
. Variabel itu berasalpdksh
dan tidak pernah berhasil mencapai AT&T ksh88.FCEDIT
.posh
(pdksh dengan sebagian besar fitur non-POSIX dihapus sehingga Anda mungkin ingin menyebutnya "sh") tidak memiliki FCEDIT atau KSH_VERSION tetapi memiliki PS3 (mungkin tidak lama), meskipun tidak mungkin bagi seseorang untuk memilikinya sebagai shell login . Perhatikan juga bahwa kode di atas tidak mencerminkan apakah adabash
atauzsh
dalamsh
mode emulasi, yang mungkin menjadi masalah jika Anda menggunakan$PROFILE_SHELL
untuk memutuskan apakah akan mengaktifkan fitur ini atau itu. Lihat juga kulit Sven Mascheck untuk informasi lebih lanjut yang mungkin (atau mungkin tidak) ingin Anda periksa.Kamu bisa mencoba
yang akan memberi Anda nama perintah yang terkait dengan pid skrip.
sumber
cmd
kecomm
ketika POSIXifying jawabannya.Jika ada
lsof
perintah yang tersedia di sistem Anda, Anda bisa mendapatkan path lengkap dari shell induk yang dapat dieksekusi dengan mendapatkan PID induk melaluips
dan mem-parsing ouputlsof -p $ppid
(lihat Bagaimana menentukan shell saat ini yang sedang saya kerjakan? ).sumber
/
, jika saya menggunakanNR==4
saya mendapatkan path ke induk shell.sh
memiliki$PPID
variabel. AktifLinux
, Anda bisa menggunakanreadlink -f "/proc/$PPID/exe"
.Di luar tanah Linux atau tidak memiliki akses ke sistem file / proc atau equivelent, Anda dapat menggunakan pstree:
Dengan asumsi Anda memiliki pid
Di Mac:
Di kotak Linux:
Format dan gaya output dari pstree berbeda, tergantung pada lingkungan Anda, tetapi Anda dapat memaksakan output ASCII dan kemudian sed / tr / awk / etc. filter output untuk mendapatkan shell yang menjalankan skrip.
Jadi versi keluaran yang dibersihkan (berfungsi untuk Mac atau Linux OS):
Hasil yang sedang berjalan:
Dan ketika dijalankan dengan shell yang berbeda:
Hasil:
Tidak diperlukan root atau sistem file khusus. Catatan, pemfilteran saya mengasumsikan bahwa nama biner shell diakhiri dengan sh dan bahwa tidak ada entri perantara yang diakhiri dengan sh. Juga berasumsi bahwa Anda tidak memberi nama skrip Anda "sh" atau beberapa pola grep yang disayangkan yang akan menghapus informasi. :) Akan memerlukan beberapa penyesuaian untuk lingkungan Anda sendiri untuk memastikan tingkat yang lebih tinggi dari yang sangat mudah.
sumber
Anda dapat menggunakan perintah:
untuk mengetahui shell dari dalam skrip.
sumber
$SHELL
adalah shell pilihan pengguna. Diinisialisasi dari shell login pengguna. Tidak ada hubungannya dengan shell yang sedang berjalan.