我有多少貝殼?
問題:找出我有多少貝殼。
詳細資訊:我經常從 vim 打開 shell。建構並執行並退出。有時我會忘記並在裡面打開另一個vim,然後再打開一個shell。:(
我想知道我有多少貝殼,甚至可能一直在我的貝殼螢幕上。(我可以管理那部分)。
我的解決方案:解析程序樹並查找 vim 和 bash/zsh 並找出目前程序在其中的深度。
類似的東西已經存在了嗎?我什麼也找不到。
當我讀到你的問題時,我的第一個想法是
$SHLVL
。然後我看到你想計算除了shell 級別之外的級別vim
。 一個簡單的方法是定義一個 shell 函式:vim() { ( ((SHLVL++)); command vim "$@");}
SHLVL
每次鍵入vim
命令時,這將自動且無提示地遞增。您將需要為您曾經使用的vi
/的每個變體執行此操作;vim
例如,vi() { ( ((SHLVL++)); command vi "$@");} view() { ( ((SHLVL++)); command view "$@");}
外圓括號創建了一個子shell,因此手動更改 的值
SHLVL
不會污染目前(父)shell 環境。當然,command
關鍵字是為了防止函式呼叫自己(這將導致無限遞歸循環)。當然,您應該將這些定義放入您的.bashrc
或其他 shell 初始化文件中。上面有一點效率低下。在某些 shell 中(bash 是其中之一),如果你說
**(***命令1***;** *命令2***;** …… **;** *命令n***)**
where是一個外部的可執行程序(即,不是內置命令),shell 保留了一個額外的程序,只是等待終止。這(可以說)沒有必要;優點和缺點是有爭議的。如果您不介意佔用一點記憶體和一個程序槽(並且在執行 a 時看到比您需要的更多的 shell 程序),那麼請執行上述操作並跳到下一部分。如果您使用的外殼不會保留額外的程序,則同上。但是,如果你想避免額外的過程,首先要嘗試的是
*cmdn*``*cmdn*``ps
vim() { ( ((SHLVL++)); exec vim "$@");}
該
exec
命令用於防止額外的 shell 程序延遲。但是,有一個問題。shell 的處理
SHLVL
有點直覺:當 shell 啟動時,它會檢查是否SHLVL
已設置。如果未設置(或設置為非數字),則 shell 將其設置為 1。如果已設置(設置為數字),則 shell 將其加 1。但是,按照這個邏輯,如果你說
exec sh
,你SHLVL
應該上去。但這是不可取的,因為您的真實外殼級別沒有增加。外殼通過從 您執行以下操作時減去一個來處理此問題:SHLVL``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
所以
vim() { ( ((SHLVL++)); exec vim "$@");}
是洗;它
SHLVL
只會增加以再次減少它。您不妨只是說vim
,沒有功能的好處。注意:
根據 Stéphane Chazelas(他什麼都知道)的說法,一些 shell 足夠聰明,如果它位於子 shell 中,則不會這樣做
exec
。要解決這個問題,你會做
vim() { ( ((SHLVL+=2)); exec vim "$@");}
然後我看到你想獨立於shell 級別來計算級別
vim
。 好吧,完全相同的技巧有效(好吧,稍作修改):vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(等等
vi
,view
等)export
是必要的,因為VILVL
預設情況下未定義為環境變數。但它不需要成為函式的一部分;你可以說export VILVL
作為一個單獨的命令(在你的.bashrc
)。並且,如上所述,如果額外的 shell 程序對您來說不是問題,您可以command vim
代替exec vim
,而不要SHLVL
理會:vim() { ( ((VILVL++)); command vim "$@");}
個人偏好:
您可能想重命名
VILVL
為VIM_LEVEL
. 當我看“VILVL
”時,我的眼睛很痛;他們無法判斷這是“vinyl”的拼寫錯誤還是羅馬數字格式錯誤。如果您使用的shell 不支持
SHLVL
(例如dash),您可以自己實現它,只要該shell 實現一個啟動文件。只是做類似的事情if [ "$SHELL_LEVEL" = "" ] then SHELL_LEVEL=1 else SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1) fi export SHELL_LEVEL
在您
.profile
或適用的文件中。(您可能不應該使用名稱SHLVL
,因為如果您開始使用支持 的外殼,那將導致混亂SHLVL
。)其他答案已經解決了將環境變數值嵌入到您的 shell 提示符中的問題,所以我不會重複這一點,尤其是您說您已經知道該怎麼做。