2015-09-25 74 views
-1
#!/bin/sh 
count=0 
foo=0 

echo "foo is $foo" 

while [ "$foo" -eq 0 ] && [ "$count" -lt 10 ]; do 
    echo "inside while: foo is $foo" 
    count=$((count+1)) 
    foo=1 
done 

echo "after while" 

你會期望上面的腳本輸出以下內容,對吧?我的殼破了嗎?

foo is 0 
inside while: foo is 0 
after while 

而且它在很多其他機器上都有,就像你自己的機器一樣。但不是我的...

foo is 0 
inside while: foo is 0 
inside while: foo is 1 
inside while: foo is 1 
... (infinite loop) 

我做錯了什麼,或者我錯過了明顯的東西?

在這個(壞掉的)機器上,如果我調整while有條件使用「過時」-a操作符,它會「修復」問題(不管它是什麼)。爲什麼?

+1

要調查的第一件事是什麼樣的shell和版本是你的/ bin/sh? - 然後調查在該shell啓動時運行的任何啓動腳本。 – nos

+0

......這就是說 - 正如我在你的其他問題中所建議的那樣,你會考慮使用'set -x'來記錄運行時的單個命令嗎?實際上,我可以考慮在腳本中隱藏字符的可能方式可能會導致此行爲,並且使用'set -x'可以清楚地表明是否是這種情況。 –

+0

(從'-eq'切換到'=' - 因此,使基於字符串的比較而不是數字 - 實際上會使您更加堅固,以對抗我懷疑的故障模式)。 –

回答

1

假設您的腳本文本中沒有隱藏字符(假設我建議在驗證中付出一些努力!),這確實表現出與POSIX sh標準相反的行爲。

n1 -eq n2 - 如果整數n1和n2在代數上相等,則爲真;否則,是錯誤的。

值得注意的是,這並沒有規定或保證如果兩個參數實際上不是一個整數會發生什麼;例如,如果它是將是的整數,但在結尾處具有回車符或其他非打印字符。

其他項目的嘗試,依次是:

  • 運行sh -x yourscript,並期待在運行循環的時候叫test確切的論據。同時確定&&鏈中的第二次測試是否完全運行。
  • 您的運營商改變從-eq=,運行一個字符串比較,而不是數值比較(從而確保包含隱藏字符的任意字符串將無法與字符串0成功地比較,而不是在這種情況下,依靠未定義行爲) 。
  • [ "$foo" -eq 0 ]替換爲false,並確保循環的內容不會運行(因此可以理智地檢查shell實現的某些其他核心部分)。