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 vimkomut her yazışınızda otomatik olarak ve sessizce artar . Sen her varyant için bunu yapmak gerekir vi/ ' vimHiç 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 commandanahtar 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 .bashrcya 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 şeycmdncmdnps
vim() { ( ((SHLVL++)); exec vim "$@");}
execKomut kalıcı ekstra kabuk sürecini engellemek için vardır.
Ama bir tane var. Kabuğun kullanımı SHLVLbiraz sezgiseldir: Kabuk başladığında, SHLVLayarlanmış 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, SHLVLyü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; SHLVLyalnızca tekrar azaltmak için artar . vimBir 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 execbir kabuktaki olduğunu.
Bunu düzeltmek için yapardın
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Sonra vimseviyelerini
, 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, viewvs.) exportiçin gerekli olan VILVLvarsayılan bir ortam değişkeni olarak tanımlanmamıştır. Fakat işlevin bir parçası olması gerekmez; Sadece export VILVLayrı 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 vimonun yerine yapabilir exec vimve SHLVLyalnız bırakabilirsiniz :
vim() { ( ((VILVL++)); command vim "$@");}
Kişisel Tercih:
Bunun VILVLgibi 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 .profileya 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.
$SHLVLdeğişken, aradığınızı (birkaç kabukları tarafından tutulan)?