2012-12-17 57 views
0

我意識到採購腳本並執行腳本的唯一區別是在後一種情況下,父級環境保持不受影響。採購腳本並在KornShell上執行腳本時行爲上的差異

考慮此示例腳本:

SETUP_DIR=`dirname $0` 
echo $SETUP_DIR 
echo $0 
echo $1 

上述腳本只是取運行腳本的目錄名。雖然試圖採購它,上面的腳本失敗,出現以下錯誤

$ . test.sh foo 
dirname: invalid option -- k 
Try `dirname --help' for more information. 

-ksh 
foo 

什麼,似乎對我來說,採購它的時候,作爲腳本父環境shell中運行,外殼名作爲傳遞的原因第一個參數,在這種情況下它的-ksh。因爲-k,這是dirname

奇怪的是無效選項的

dirname -ksh失敗,這個問題是不存在的SH或bash

$ sh 
sh-3.2$ . test.sh foo 
. 
sh 
foo 
sh-3.2$ bash 
bash-3.2$ . test.sh foo 
. 
bash 
foo 
bash-3.2$ 
  • 所以我想知道運行的同時,它是KornShell(ksh)中已知的已記錄行爲嗎?如何解決這個問題?
  • 我的第二個通用的問題是,爲什麼dirname 'sh'返回當前目錄.
+0

我無法重現你的錯誤。 'dirname -ksh'是否適合你? '哪個dirname'給你什麼? – dogbane

+0

@dogbane:'dirname -ksh'不起作用,並在我的問題中提到失敗。我在問題本身已更新的其他相關信息。 – Abhijit

回答

1

所以我想知道,這是一個已知的玉米殼記錄的行爲?如何解決這個問題?

當KSH被/bin/login開始作爲一個登錄shell,其$0-前綴,所以$0-ksh,而不是僅僅ksh/bin/kshLogin does this to indicate to the shell that it is being started as a login shell,因爲這通常會影響配置文件加載。如果外殼被執行exec(2)和參數爲零($ 0)的第一個字符調用

是 - ,那麼外殼被假定爲:

的KSH手動記錄其遵守本公約是一個登錄外殼,命令從[...]

連字符前綴不會顯示給我用bash,我假定bash編輯命令行以阻止它在進程列表中可見。

結果,dirname $0dirname -ksh和目錄名試圖解析爲傳遞ksh選項

可以通過顯式終止選擇通過dirname--解析解決這個問題,即

dirname -- "$0" 

我的第二個通用問題是,爲什麼dirname'sh'返回當前目錄。

dirname正試圖幫助並返回一個可用的路徑,即使您沒有給出路徑的目錄部分。由於您的「$ 0」只有一個組成部分,它假定它是相對於當前工作目錄,即sh == ./sh,並返回.

這被記錄爲每羅布麻的答案

+0

有趣。我認爲這將會消除我目前的好奇心。感謝您的幫助 – Abhijit

+0

當我運行'dirname -ksh'時,我得到'.'。 – dogbane

+0

@dogbane你可能有不同的'dirname'實現,例如作爲內置的shell。我是gnu的'/ usr/bin/dirname' coreutils – je4d

1

在回答你的第二個問題,從man dirname

打印名稱與它的尾部/組件刪除;如果NAME不包含 /,則輸出'。'。 (意思是當前目錄)。

這就是爲什麼當您運行dirname sh時得到.

我無法在ksh中重現您的錯誤。

+0

謝謝。我剛剛學到了一些新的:-) – Abhijit