Di saya .profile
, saya menggunakan kode berikut untuk memastikan bahwa alias dan fungsi terkait Bash hanya bersumber jika shell login sebenarnya adalah Bash :
# If the current (login) shell is Bash, then
if [ "${BASH_VERSION:-}" ]; then
# source ~/.bashrc if it exists.
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
Saat ini saya sedang dalam proses meletakkan file konfigurasi shell, skrip dan fungsi saya di bawah kontrol versi. Saya juga baru saja mulai proses menghilangkan Bashisms kasual dari script shell yang tidak mendapatkan keuntungan dari fitur Bash-spesifik, misalnya, mengganti function funcname()
dengan funcname()
.
Untuk repositori file shell saya, saya telah mengonfigurasi hook pre-commit yang menjalankan checkbashisms
utilitas dari paket devscripts Debian pada setiap sh
file dalam repositori untuk memastikan bahwa saya tidak secara tidak sengaja memperkenalkan sintaks spesifik-Bash. Namun, ini memunculkan kesalahan untuk .profile
:
possible bashism in .profile line 51 ($BASH_SOMETHING):
if [ "${BASH_VERSION:-}" ]; then
Saya bertanya-tanya apakah ada cara untuk memeriksa shell mana yang berjalan yang tidak akan memicu peringatan checkbashisms
.
Saya memeriksa daftar variabel terkait shell yang terdaftar oleh POSIX dengan harapan salah satu dari mereka dapat digunakan untuk menampilkan shell saat ini. Saya juga telah melihat variabel yang ditetapkan dalam shell Dash interaktif tetapi, sekali lagi, gagal menemukan kandidat yang cocok.
Saat ini, saya sudah dikecualikan .profile
dari sedang diproses oleh checkbashisms
; ini adalah file kecil sehingga tidak sulit untuk memeriksanya secara manual. Namun, setelah meneliti masalah ini, saya masih ingin tahu apakah ada metode yang sesuai dengan POSIX untuk menentukan shell mana yang berjalan (atau setidaknya cara yang tidak menyebabkan checkbashisms
kegagalan).
Latar belakang / klarifikasi lebih lanjut
Salah satu alasan saya meletakkan file konfigurasi shell saya di bawah kontrol versi adalah untuk mengkonfigurasi lingkungan saya di semua sistem yang saya masuki secara teratur: Cygwin, Ubuntu dan CentOS (keduanya 5 dan 7, menggunakan Active Directory untuk pengguna autentikasi). Saya paling sering masuk melalui X Windows / lingkungan desktop dan SSH untuk host jarak jauh. Namun, saya ingin ini menjadi bukti masa depan dan memiliki sedikit ketergantungan pada ketergantungan sistem dan alat lain mungkin.
Saya telah menggunakan checkbashisms
sebagai pemeriksaan kewarasan otomatis sederhana untuk sintaksis file terkait shell saya. Ini bukan alat yang sempurna, misalnya, saya sudah menerapkan tambalan sehingga tidak mengeluh tentang penggunaan command -v
dalam skrip saya. Saat meneliti, saya telah belajar bahwa tujuan sebenarnya dari program ini adalah untuk memastikan kepatuhan dengan kebijakan Debian yang, seperti yang saya pahami, didasarkan pada POSIX 2004 dan bukan 2008 (atau revisi 2013).
sumber
.bash_profile
sumber yang keduanya.profile
dan (kondisional).bashrc
.Jawaban:
Anda
kode benar-benar sesuai POSIX dan cara terbaik untuk memeriksa bahwa Anda sedang berjalan
bash
. Tentu saja$BASH_VERSION
variabelnya khusus untuk bash, tapi itu sebabnya Anda menggunakannya! Untuk memeriksa apakah Anda menjalankanbash
!Catatan yang
$BASH_VERSION
akan ditetapkan apakahbash
dipanggil sebagaibash
ataush
. Setelah Anda menegaskan bahwa Anda sedang menjalankanbash
, Anda dapat menggunakan[ -o posix ]
sebagai indikator bahwa shell dipanggil sebagaish
(meskipun opsi itu juga diatur ketika POSIXLY_CORRECT berada di lingkungan ataubash
dipanggil dengan-o posix
, atau dengan SHELLOPTS = posix di lingkungan. Tetapi dalam semua kasus itu,bash
akan berperilaku seolah-olah disebut sebagaish
).Variabel lain yang bisa Anda gunakan alih-alih
$BASH_VERSION
dan yangcheckbashism
tampaknya tidak mengeluh kecuali melewati-x
opsi tersebut$BASH
. Itu juga spesifik untuk yangbash
Anda juga harus dapat digunakan untuk menentukan apakah Anda sedang berlaribash
atau tidak.Saya juga berpendapat itu bukan penggunaan yang tepat
checkbashisms
.checkbashisms
adalah alat untuk membantu Anda menulissh
skrip portabel (sesuaish
spesifikasi dalam kebijakan Debian, superset dari POSIX), ini membantu mengidentifikasi sintaksis non-standar yang diperkenalkan oleh orang yang menulis skrip pada sistem di manash
terdapat symlinkbash
.A
.profile
ditafsirkan oleh cangkang yang berbeda, banyak di antaranya yang tidak sesuai dengan POSIX. Secara umum, Anda tidak menggunakansh
sebagai shell login Anda, tetapi shell sukazsh
,fish
ataubash
dengan fitur interaktif yang lebih maju.bash
danzsh
, ketika tidak dipanggil sebagaish
dan ketika file sesi profil masing-masing (.bash_profile
,.zprofile
) tidak sesuai POSIX (terutamazsh
) tetapi masih dibaca.profile
.Jadi itu bukan sintaks POSIX yang Anda inginkan
.profile
tetapi sintaks yang kompatibel dengan POSIX (untuksh
),bash
danzsh
jika Anda pernah menggunakan shell tersebut (bahkan mungkin Bourne sebagai shell Bourne juga membaca.profile
tetapi tidak umum ditemukan pada sistem berbasis Linux ).checkbashisms
pasti akan membantu Anda mengetahui bashism tetapi mungkin tidak menunjukkan sintaks POSIX yang tidak kompatibel denganzsh
ataubash
.Di sini, jika Anda ingin menggunakan
bash
kode-spesifik (seperti menyelesaikanbash
bug yang tidak dibaca~/.bashrc
di shell login interaktif), pendekatan yang lebih baik adalah dengan~/.bash_profile
melakukan itu (sebelum atau setelah sumber di~/.profile
mana Anda meletakkan sesi umum Anda inisialisasi).sumber
checkbashisms
karena variabel yang digunakan.$0
untuk kasus khusus ini?sh
dan beberapa shell lain disebut sebagaish
.dash
atau shell non-bash lainnya tidak tepat disebut denganargv[0] == "bash"
, yang sepenuhnya legal, jika tidak mungkin.Biasanya orang menggunakan
$0
untuk tujuan ini. Di situs yang Anda tautkan berdiri:sumber
$0
untuk nama skrip shell, yang saya bersihkan lupa bahwa itu juga dapat merujuk ke shell saat ini. Terima kasih!exec
keluarga karena memungkinkan program panggilan untuk mengidentifikasi biner dijalankan secara terpisah dari string yang akan diteruskan sebagai argumen 0.Biasanya variabel lingkungan SHELL memberi tahu Anda shell default. Anda seharusnya tidak perlu mencari file .bashrc secara manual (tidak benar melihat pembaruan di bawah), bash harus melakukan ini secara otomatis hanya pastikan itu ada di direktori $ HOME.
Pilihan lainnya adalah melakukan sesuatu seperti:
yang akan memberi tahu Anda perintah (tanpa argumen, = tanpa nilai tidak akan menampilkan tajuk kolom) dari proses saat ini. Contoh output:
MEMPERBARUI:
Saya berdiri dikoreksi! :)
.Bashrc tidak selalu bersumber seperti yang disebutkan dalam komentar di bawah dan /programming/415403/whats-the-difference-between-bashrc-bash-profile-and-environment
Jadi, Anda dapat memindahkan .bashrc ke .bash_profile dan melihat apakah itu berhasil tanpa harus melakukan tes. Jika tidak, Anda memiliki tes di atas.
sumber
.bashrc
sebenarnya tidak bersumber dari shell login tetapi.profile
(jika ada) atau.bash_profile
sedang.SHELL
tidak ditentukan oleh POSIX dan sayangnya, tidak adacmd
opsi format untukps
.ps -o cmd= $$
seharusnya bekerja cukup banyak di mana-mana,$SHELL
variabelnya sama sekali tidak relevan. Itu adalah shell default pengguna dan tidak memiliki kaitan dengan shell apa yang sedang dijalankan atau apa shell yang menjalankan skrip shell.~/.profile
ketika dimulai sebagai cangkang login. Jadi, misalnya, Anda$SHELL
bisacsh
dan Anda berlaribash -l
. Itu akan mulai bash sebagai shell login, jadi itu akan membaca~/.profile
, tetapi Anda$SHELL
akan tetap menunjuk kecsh
. Plus,.profile
mungkin bersumber secara eksplisit oleh skrip lain. Karena OP akan mencapai ketahanan maksimum, semua jenis kasing harus dipertimbangkan. Bagaimanapun,$SHELL
tidak memberikan informasi berguna tentang shell yang sedang berjalan.SHELL
tidak ditentukan oleh POSIX: pubs.opengroup.org/onlinepubs/9699919799/basedefs/...Pertanyaannya menanyakan shell login pengguna serta shell saat ini dengan cara yang sesuai
checkbashisms
. Jika itu dimaksudkan sebagai shell di mana pengguna masuk, saya akan menggunakan yang dari/etc/passwd
, misalnya,Pengguna tentu saja dapat memulai shell baru setelah masuk. Tentu saja, jika satu bash dan yang lainnya tidak, tes variabel lingkungan bash mungkin tidak membantu.
Beberapa mungkin ingin menggunakan
getent
bukan hanyapasswd
file (tapi itu tidak akan berada dalam ruang lingkup pertanyaan).Berdasarkan komentar tentang LDAP, dan saran untuk
logname
, formulir alternatif ini dapat digunakan:Saat mengujinya, saya perhatikan bahwa
logname
tidak suka inputnya dialihkan (jadi saya meninggalkan ekspresi terpecah). Pemeriksaan cepatgetent
harus dilakukan pada platform yang disebutkan (meskipun itu seharusnya disediakan dalam pertanyaan awal):sumber
$(logname)
).id
atau variabel yang dapat dimodifikasi pengguna adalah pilihan yang berbeda.$(logname)
, tidak$LOGNAME
. ID pengguna dan shell login keduanya berasal dari nama pengguna yang digunakan saat login. Anda tidak dapat kembali dari id pengguna ke shell login kecuali pada sistem di mana hanya ada satu nama pengguna per id pengguna. Atau TKI, kunci utama dalam database pengguna adalah nama pengguna, bukan uid.