2014-07-22 67 views
9

我正在編寫一個腳本,我需要在幾個地方使用文件測試的輸出,包括一個shell函數。我想將文件存在分配給shell變量,如下所示:file_exists=[ -f $myfile ]將'test'的結果賦值給一個變量

只是爲了確保我有我的基地覆蓋,我開始通過觸摸一個文件,並測試它的存在:

file='a' 
touch $file 
if [ -f $file ] 
then 
    echo "1 -- '$file' exists" 
fi 

輸出:

1 -- 'a' exists 

該文件已成功創建 - 沒有意外,但至少我知道我沒有處理任何權限問題或任何問題。

接下來我測試,以確保我可以存儲在變量布爾表達式:

mytest=/bin/true 

if $mytest 
then 
    echo "2 -- \$mytest is true" 
fi 

輸出:

2 -- $mytest is true 

所以我已經得到了基本覆蓋 - 條件表達式應該發出與/bin/true/bin/false相同的輸出...但這不是我所看到的:

mytest=[ -f $file ] 
if $mytest 
then 
    echo "3 -- \$mytest is true [expect true]" 
else 
    echo "3 -- \$mytest is false [expect true]" 
fi 

這種失敗,出現以下錯誤:

-f: command not found 

我得到同樣的錯誤消息,如果我使用test -f $file而非[ -f $file ]

如果我在[前面加一個空格,該錯誤消失......

mytest= [ -f $file ] 
if $mytest 
then 
    echo "4 -- \$mytest is true [expect true]" 
else 
    echo "4 -- \$mytest is false [expect true]" 
fi 

輸出似乎是正確的:

4 -- $mytest is true [expect true] 

...但如果我刪除該文件,我應該得到相反的結果:

rm $file 
mytest= [ -f $file ] 
if $mytest 
then 
    echo "5 -- \$mytest is true [expect false]" 
else 
    echo "5 -- \$mytest is false [expect false]" 
fi 

...我不要:

5 -- $mytest is true [expect false] 

爲了公平起見,我期望與真值的空間亂:

mytest= /bin/false 
if $mytest 
then 
    echo "6 -- \$mytest is true [expect false]" 
else 
    echo "6 -- \$mytest is false [expect false]" 
fi 

輸出:

6 -- $mytest is true [expect false] 

那麼,我該如何存儲在內置的test輸出一個shell變量?

+0

'mytest的=/bin中/ TRUE'這是存儲** **串'/斌/真''mytest'變量中。 –

回答

21

正如其他人在這裏證明,使用字符串「真」是一個紅色的鯡魚;這是而不是在shell腳本中存儲布爾值的適當方式,因爲評估它意味着動態調用命令,而不是簡單地在腳本中使用硬編碼的shell內建腳本檢查存儲的值。

相反,如果你真的必須存儲退出狀態,做這樣一個數值:

[ -f "$file" ]    # run the test 
result=$?     # store the result 

if ((result == 0)); then # 0 is success 
    echo "success" 
else       # nonzero is failure 
    echo "failure" 
fi 
3

mytest=/bin/true被存儲/bin/true$mytest變量。

mytest=[ -f $file ]$mytest變量設置爲值[該命令-f $file ](其作爲輸出指示失敗有,因爲沒有-f命令可用)的持續時間。

mytest= [ -f $file ](如以上所述)的$mytest變量的值設定爲空白爲[ -f $file ]命令的持續時間(並返回任何[返回)。

mytest= /bin/false這與上述情況相同,只有正在運行的命令是/bin/false

如果你想存儲在一個變量命令的返回碼,你可以做

/bin/true 
ret=$? 

,如果你想存儲在一個變量命令的輸出,你可以做

out=$(/bin/true) 

(儘管用/bin/true表示變量將爲空,因爲它不輸出文字。)

對於您的情況,您希望前者$?型號。

另外,在腳本中使用set -x(和/或set -v)可能會幫助您診斷此問題。

+0

實際上,稍後會有悲傷......當我存儲'$?'的值時,我不能在以後重新測試它 - 'testme = $ ?;如果$ testme;然後回顯「ts-da」;其他回聲「bzzzt」; fi'給出'-bash:0:command not found',因爲'if'語句試圖將其參數作爲命令運行並評估該命令的成功。 –

+1

正確,你不運行該變量。你檢查它的價值。它是'0'還是別的什麼。'if [「$ testme」-eq 0];然後' –

6

需要引用空白:

mytest='[ -f $file ]' 
if $mytest; then echo yes; fi 

然而,這是非常脆,可能不安全。請參閱http://mywiki.wooledge.org/BashFAQ/050瞭解詳細的討論和一些更好的方法來完成類似的事情。

如果你想封裝的代碼複雜的一塊,一個功能通常是要走的路:

mytest() { [ -f "$file" ]; } 
if mytest; then echo yes; fi 

如果你想一次運行的代碼,並保存它的結果,所以你以後可以檢查它,我會改寫這樣的:

if [ -f "$file" ]; then 
    mytest=true 
else 
    mytest=false 
fi 
if $mytest; then echo yes; fi 
+0

我在這裏分裂; BashFAQ#50的參考資料總是值得一提的,但如果顯示'mytest = [-f $ file]'沒有顯示更好的練習,那麼可以鼓勵懶惰的使用它,儘管有警告。 –

+0

我不得不同意,但我真的無法猜測OP究竟希望如此。 – tripleee

+0

我不確定任何猜測是必要的;你能想到任何用例(*任何*用例),其中樣本代表目前給出的適當做法嗎? –