Sorunuzu okuduğumda ilk düşüncem buydu $SHLVL
. Sonra kabuk seviyelerine ek olarakvim
seviyeleri
saymak istediğini gördüm . Bunu yapmanın basit bir yolu, bir kabuk işlevi tanımlamaktır:
vim() { ( ((SHLVL++)); command vim "$@");}
Bu, SHLVL
bir vim
komut her yazışınızda otomatik olarak ve sessizce artar . Sen her varyant için bunu yapmak gerekir vi
/ ' vim
Hiç kullanın; Örneğin,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
Dış parantez seti alt kabuk yaratır, dolayısıyla değerdeki manüel değişim SHLVL
mevcut (üst) kabuk ortamını kirletmez. Elbette command
anahtar kelime, işlevlerin kendilerini çağırmasını önlemek için vardır (bu da sonsuz bir özyinelemeyle sonuçlanır). Ve tabii ki bu tanımları sizin .bashrc
ya da başka bir kabuk başlatma dosyasına koymalısınız .
Yukarıdakilerde hafif bir verimsizlik var. Bazı mermilerde (bir bash bash)
( cmd 1 ; cmd 2 ; … ; cmd n )
Nerede bir dış, çalıştırılabilir bir program (yani değil yerleşik bir komutu), kabuk sadece beklemek, ortalıkta ekstra bir işlem tutar olduğunu sonlandırmak için. Bu (tartışmalı) gerekli değildir; avantajları ve dezavantajları tartışmalıdır. Biraz bellek ve bir işlem yuvası bağlamak (ve istediğinizde bir tane daha fazla kabuk işlemi görmek için) sakıncası yoksa, yukarıdakileri yapın ve bir sonraki bölüme geçin. Ekstra işlemin devam etmesini önleyen bir kabuk kullanıyorsanız, aynı işlemi yapın. Ancak, fazladan işlemden kaçınmak istiyorsanız, denenecek ilk şeycmdn
cmdn
ps
vim() { ( ((SHLVL++)); exec vim "$@");}
exec
Komut kalıcı ekstra kabuk sürecini engellemek için vardır.
Ama bir tane var. Kabuğun kullanımı SHLVL
biraz sezgiseldir: Kabuk başladığında, SHLVL
ayarlanmış olup olmadığını kontrol eder . Ayarlanmadıysa (veya sayıdan başka bir şeye ayarlanmışsa), kabuk onu 1'e ayarlar. Ayarlanmışsa (sayıya), kabuk ona 1 ekler.
Ancak, bu mantıkla söylerseniz exec sh
, SHLVL
yükselmelisiniz. Ancak bu istenmeyen bir durumdur çünkü gerçek kabuk seviyeniz artmamıştır. Kabuk bu işler bir çıkarılmadan gelen SHLVL
bir yaptığınızda 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
Yani
vim() { ( ((SHLVL++)); exec vim "$@");}
bir yıkama; SHLVL
yalnızca tekrar azaltmak için artar . vim
Bir işlevden yararlanmadan, sadece söyleyebilirsiniz .
Not:
(her şeyi bilir) Stéphane Chazelas göre , bazı kabukları yeterince akıllı değil , bunu yapmak için exec
bir kabuktaki olduğunu.
Bunu düzeltmek için yapardın
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Sonra vim
seviyelerini
, kabuk seviyesinden bağımsız olarak saymak istediğini gördüm . Tam olarak aynı numara işe yarıyor (küçük bir değişiklikle):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(ve böylece için ilgili vi
, view
vs.) export
için gerekli olan VILVL
varsayılan bir ortam değişkeni olarak tanımlanmamıştır. Fakat işlevin bir parçası olması gerekmez; Sadece export VILVL
ayrı bir komut olarak söyleyebilirsiniz (içinde .bashrc
). Ve yukarıda tartışıldığı gibi, ekstra kabuk işlemi sizin için bir sorun değilse, command vim
onun yerine yapabilir exec vim
ve SHLVL
yalnız bırakabilirsiniz :
vim() { ( ((VILVL++)); command vim "$@");}
Kişisel Tercih:
Bunun VILVL
gibi bir şeyi yeniden adlandırmak isteyebilirsiniz VIM_LEVEL
. “ VILVL
” Ye baktığımda gözlerim ağrıyor; “vinil” nin yanlış yazıldığını mı yoksa hatalı biçimlendirilmiş bir Roma rakamının mı olduğunu söyleyemezler.
Desteklemeyen bir kabuk kullanıyorsanız SHLVL
(örneğin çizgi), kabuk bir başlangıç dosyası uyguladığı sürece kendiniz uygulayabilirsiniz. Sadece böyle bir şey yap
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
senin içinde .profile
ya da ilgili dosyanın. (Büyük olasılıkla adı kullanmamalısınız, SHLVL
çünkü destekleyen bir kabuk kullanmaya başlarsanız bu kaosa neden olur SHLVL
.)
Diğer cevaplar, ortam değişken değerlerinin kabuk istemi içine gömülmesi sorununu çözmüştür, bu yüzden bunu tekrarlamam, özellikle de zaten nasıl yapılacağını bildiğinizi söylersiniz.
$SHLVL
değişken, aradığınızı (birkaç kabukları tarafından tutulan)?