2013-10-08 103 views
0

我有一個初始化文件(/etc/profile.d/which2.sh),它在任何shell啓動時都將'which'命令替換爲別名。在bash或sh中很好,但在zsh中,我不希望這是一個已經知道別名和函數的內置函數。在zsh下如何讓腳本「知道」,而不是執行別名?如何知道我的shell正在運行我的init文件?

$ 0不幫助。

我已經通過簡單地在解封特定的zsh〜/ .zshrc別名解決了問題,但我想知道的另一種方式。

回答

3

如何

[ "$(which which)" = /usr/bin/which ] && alias which "whichever" 

這並不驗證名殼的;而是驗證外殼的行爲。這是一個普遍適用的編程範例的實例:儘可能直接測試行爲。 (例如,請參閱瀏覽器檢測。)

在這種情況下,如果您只是將外殼的名稱作爲行爲檢查的代理進行檢查,那麼現在可能運行良好,但未來可能會中斷。這個名字實際上是任意的,並且可以很容易地引入新的名字。例如,在一些發行版ksh是一個硬鏈接到zsh; zsh將調整其行爲以模仿ksh。作爲另一個例子,我有兩個不同的zsh版本,其中一個被調用爲zsh5

理想地,該測試將不依賴於which效用的精確位置,無論是。

+0

這並不測試實際的shell。 – Demi

+1

@Demetri:那是真的。它測試shell的*行爲*,因此即使您的安裝將'zsh'重命名爲'z_shell',它也可以工作。但如你所願。 – rici

+0

你是對的。對不起,您可以以任何方式編輯您的答案,我將能夠刪除它,並用upvote替換它。 – Demi

0

SHELL環境變量包含完整路徑殼的二進制文件。你可以使用(或它的基名):

s=$(basename $SHELL) 
[ "$s" = 'zsh' ] || alias which="what you want it to be" 
+0

根據我的理解,'$ SHELL'只設置一次到_login_ shell的值。因此,即使在稍後運行不同的shell時,'$ SHELL'也會保持相同的值 - 它不一定反映當前正在執行的shell。一些shell(但不是全部)設置特定於shell類型的變量,例如'$ BASH_VERSION'或'$ ZSH_VERSION';例如,「破折號」不會。 – mklement0

+0

你說得對。不知道! – Coroos

0

@rici's approach最適合在手的情況下,但以防萬一你需要知道當前正在執行具體殼[執行]:

檢查值$0

  • 它指向外殼二進制作爲調用,即,該值可以是一個單純的文件名或路徑。
  • 在OSX,該值可以與-前綴,即如果外殼是一個登錄殼;例如-bash

注意:請勿使用$SHELL,因爲它僅在登錄時設置一次 - 登錄shell的路徑。即使稍後運行其他shell,它的值也不會改變。

因此,獲得當前外殼程序的可執行文件名的POSIX兼容的方式是:

basename -- "${0#-}" # -> (e.g., in bash) 'bash'; will NOT work in csh/tcsh 

實例:

currShell=$(basename -- "${0#-}") # Store shell-binary filename in variable. 

[ "$(basename -- "${0#-}")" = 'zsh' ] && echo "This is a ZSH shell." 

如果它足以測試要特定的外殼只有,你可能能夠簡單地測試特定環境變量的存在,例如s $BASH_VERSION$ZSH_VERSION

但是,請注意,並非所有的殼都具有這樣的特徵變量;例如,dash沒有。

例子:

[ -n "$ZSH_VERSION" ] && echo "This is a ZSH shell." 
0

你在測試?在過去的時候,我們必須確定我們是否Kornshell或Bournshell下運行,我們可以做如下測試:

if [ "$RANDOM" = "$RANDOM" ] 
then 
    echo "This is the Bourne shell" 
    /bin/ksh $* # Script needs the Kornshell 
else 
    echo "This is the Kornshell" 
fi 

當然,無論Kornshell和Bash擴大$RANDOM(也是如此的zsh)...

好...你可以找到當前的tty運行這樣的過程:

ps -ft $(tty) 

小格式:

$ ps -ocommand="" -t$(tty) 
login -pf david 
-ksh 
bash 

相當不錯。殼以sh結束,所以我會做出這個假設。我只是想用行結束sh

$ ps -ocommand="" -t$(tty) | grep "sh$" 
-ksh 
bash 

是的,我跑在這個TTY兩發炮彈。我用Kornshell登錄,然後向外打擊。讓我們折騰PID的組合:

$ ps -t$(tty) -opid="" -ocommand="" | grep "sh$" 
62599 -ksh 
62855 bash 

我們想要的最高PID

$ ps -t$(tty) -opid="" -ocommand="" | grep "sh$" | sort -k1,1nr | head -1 
62983 bash 

是啊,我運行bash。讓我們擺脫了PID的:

$ ps -t$(tty) -opid="" -ocommand="" | grep "sh$" | sort -k1,1nr | head -1 | sed 's/.* //' 
bash 

讓我們來看看它是否有各種貝殼作品:

$ ps -t$(tty) -opid="" -ocommand="" | grep "sh$" | sort -k1,1nr | head -1 | sed 's/.* //' 
ksh 

Kornshell是罰款。

$ ps -t$(tty) -opid="" -ocommand="" | grep "sh$" | sort -k1,1nr | head -1 | sed 's/.* //' 
zsh 

工程與zsh的

$ ps -t$(tty) -opid="" -ocommand="" | grep "sh$" | sort -k1,1nr | head -1 | sed 's/.* //' 
sh 

工程與破折號或灰

% ps -t$(tty) -opid="" -ocommand="" | grep "sh$" | sort -k1,1nr | head -1 | sed 's/.* //' 
Illegal variable name. 

不tcsh中工作。好吧...你不能取悅每個人。

相關問題