Ketika saya membaca pertanyaan Anda, pikiran pertama saya adalah $SHLVL
. Lalu saya melihat bahwa Anda ingin menghitung vim
level
selain level shell. Cara sederhana untuk melakukan ini adalah dengan mendefinisikan fungsi shell:
vim() { ( ((SHLVL++)); command vim "$@");}
Ini akan secara otomatis dan diam-diam bertambah SHLVL
setiap kali Anda mengetik vim
perintah. Anda perlu melakukan ini untuk setiap varian vi
/ vim
yang pernah Anda gunakan; misalnya,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
Set kurung luar membuat subkulit, sehingga perubahan manual dalam nilai SHLVL
tidak mencemari lingkungan shell (induk) saat ini. Tentu saja command
kata kunci itu ada untuk mencegah fungsi memanggil diri mereka sendiri (yang akan menghasilkan loop rekursi tak terbatas). Dan tentu saja Anda harus meletakkan definisi ini ke dalam .bashrc
file inisialisasi shell Anda atau lainnya.
Ada sedikit inefisiensi di atas. Dalam beberapa shell (bash menjadi satu), jika Anda mengatakannya
( cmd 1 ; cmd 2 ; ... ; cmd n )
di mana ada program eksternal yang dapat dieksekusi (yaitu, bukan perintah bawaan), shell menyimpan proses tambahan di sekitar, hanya untuk menunggu untuk mengakhiri. Ini (bisa dibilang) tidak perlu; kelebihan dan kekurangannya masih bisa diperdebatkan. Jika Anda tidak keberatan mengikat sedikit memori dan slot proses (dan untuk melihat satu proses shell lebih dari yang Anda butuhkan saat melakukan a ), maka lakukan hal di atas dan lewati ke bagian berikutnya. Ditto jika Anda menggunakan shell yang tidak membuat proses ekstra berbaring. Tetapi, jika Anda ingin menghindari proses ekstra, hal pertama yang harus dicoba adalahcmdn
cmdn
ps
vim() { ( ((SHLVL++)); exec vim "$@");}
The exec
perintah yang ada untuk mencegah proses shell ekstra dari berlama-lama.
Tapi, ada gotcha. Penanganan shell SHLVL
agak intuitif: Ketika shell mulai, ia memeriksa apakah SHLVL
sudah diatur. Jika tidak disetel (atau disetel ke selain angka), shell menetapkannya ke 1. Jika disetel (ke angka), shell menambahkan 1 ke dalamnya.
Tetapi, dengan logika ini, jika Anda berkata exec sh
, Anda SHLVL
harus naik. Tapi itu tidak diinginkan, karena level shell asli Anda belum meningkat. Shell menangani ini dengan mengurangi satu dari SHLVL
saat Anda melakukan exec
:
$ echo "$SHLVL"
1
$ set | grep SHLVL
SHLVL=1
$ env | grep SHLVL
SHLVL=1
$ (env | grep SHLVL)
SHLVL=1
$ (env) | grep SHLVL
SHLVL=1
$ (exec env) | grep SHLVL
SHLVL=0
Begitu
vim() { ( ((SHLVL++)); exec vim "$@");}
adalah mencuci; itu akan menambahkan SHLVL
hanya untuk pengurangan lagi. Anda mungkin juga hanya mengatakan vim
, tanpa manfaat dari suatu fungsi.
Catatan:
Menurut Stéphane Chazelas (siapa yang tahu segalanya) , beberapa cangkang cukup pintar untuk tidak melakukan ini jika exec
ada dalam subkulit.
Untuk memperbaikinya, Anda harus melakukannya
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Lalu saya melihat bahwa Anda ingin menghitung vim
level
secara terpisah dari level shell. Nah, trik yang sama persis berfungsi (well, dengan sedikit modifikasi):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(dan seterusnya untuk vi
,, view
dll.) export
Diperlukan karena VILVL
tidak didefinisikan sebagai variabel lingkungan secara default. Tetapi tidak harus menjadi bagian dari fungsi; Anda bisa mengatakan export VILVL
sebagai perintah terpisah (di Anda .bashrc
). Dan, seperti yang dibahas di atas, jika proses shell tambahan tidak menjadi masalah bagi Anda, Anda dapat melakukan command vim
alih - alih exec vim
, dan biarkan SHLVL
sendiri:
vim() { ( ((VILVL++)); command vim "$@");}
Preferensi Pribadi:
Anda mungkin ingin mengubah nama VILVL
menjadi sesuatu seperti VIM_LEVEL
. Ketika saya melihat " VILVL
", mata saya sakit; mereka tidak tahu apakah itu salah mengeja “vinil” atau angka Romawi yang salah.
Jika Anda menggunakan shell yang tidak mendukung SHLVL
(mis., Dash), Anda bisa mengimplementasikannya sendiri selama shell mengimplementasikan file startup. Lakukan saja sesuatu seperti
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
dalam .profile
file Anda atau yang berlaku. (Anda mungkin tidak boleh menggunakan nama SHLVL
, karena itu akan menyebabkan kekacauan jika Anda mulai menggunakan shell yang mendukung SHLVL
.)
Jawaban lain telah membahas masalah menanamkan nilai variabel lingkungan ke prompt shell Anda, jadi saya tidak akan mengulanginya, terutama Anda mengatakan Anda sudah tahu bagaimana melakukannya.
$SHLVL
variabel (dikelola oleh beberapa shell) apa yang Anda cari?