2010-08-05 16 views
121

我的代碼:[:在shell編程意外操作

#!/bin/sh 
    #filename:choose.sh 
    read choose 
    [ "$choose" == "y" -o "$choose" == "Y" ] && echo "Yes" && exit 0 
    [ "$choose" == "n" -o "$choose" == "N" ] && echo "No" && exit 0 
    echo "Wrong Input" && exit 0 

但是,當我執行

sh ./choose.sh 

終端提示我,

[: 4: n: :Unexpected operator 
    [: 5: n: :Unexpected operator 

有沒有在我的bash腳本中的任何錯誤? 謝謝!

+0

當我在Linux和cygwin中執行相同的代碼時,我沒有收到任何錯誤 – Raghuram 2010-08-05 01:11:22

+2

Cygwin最有可能將'sh'替換爲'bash'。有些發行版不再提供真正的'sh'。儘管有些人會爭辯(我傾向於同意),如果你正在編寫一個可移植的腳本,用'sh'而不是'bash'來寫。 – Wolph 2010-08-05 01:27:10

+0

我的問題是,我需要'源foobar.sh'不''。/ foobar.sh' – jsta 2016-08-30 16:36:44

回答

215

。在你的bash 腳本沒有錯重寫你的腳本。但是你用SH具有那麼廣泛的語法執行;)

因此,運行bash ./choose.sh代替:)

+2

解決我的問題。謝謝! 那麼命令「sh」和「bash」之間有什麼區別嗎? – 2010-08-05 01:10:14

+3

'bash'語法是'sh'語法的超集 - 系統上的'/ bin/sh'可執行文件可能只提供標準的'sh'功能,其中不包括'[]'樣式的測試。 – Tim 2010-08-05 01:17:17

+10

是的。它們是完全不同的殼。儘管bash基於sh並基本上與sh相互兼容,並且它們實際上可能與您的系統上的程序相同,但根據您使用的名稱不同,其行爲也會有所不同。您可以通過將第一行更改爲'#!/ bin/bash'並使文件可執行並僅運行'./select.sh'來自動運行bash腳本。 – 2010-08-05 01:17:22

5

,你必須使用bash代替或使用標準SH

sh -c 'test "$choose" = "y" -o "$choose" = "Y"' 
+0

我認爲用「[]」代替「測試」會更方便。 似乎「bash ./choose.sh」可以解決問題。 – 2010-08-05 01:12:43

+0

@kit無論哪種方式,sh是更便攜的 – Anycorn 2010-08-05 01:19:08

+3

@kit.yang括號如何更方便?人們由於沒有意識到[是測試的同義詞,並且由於省略了括號內的空白而導致的持續錯誤,所以造成了歷史上的混亂,這幾乎無法彌補保存的單個字符。 (「如果[$ x = 5]」vs「如果測試$ x = 5」; 13個字符vs 14)。 – 2010-08-08 03:17:21

2

要使用bash,使用#/斌/ bash中執行它和chmod它是!可執行文件,然後使用

./choose.sh 
192

POSIX SH不明白==字符串是否相等,因爲這是一個慶典主義。改爲使用=

其他人說支架不支持sh是錯誤的,順便說一句。

+4

是的,我試着用「=」取代「==」,腳本也可以用「sh ./choose.sh」執行。bash和sh都支持括號。 – 2010-08-05 01:28:50

+25

+1這是比不必要地使用bash,IMO更好的答案。 – 2010-08-05 01:31:12

+4

給這個人一個餅乾! – tbking 2017-03-31 09:25:35

1

事實上,「[」方括號只是測試命令的內部shell別名。

所以,你可以說:

test -f "/bin/bash" && echo "This system has a bash shell" 

[ -f "/bin/bash" ] && echo "This system has a bash shell" 

...他們在任何sh或bash的等價物。請注意,要求在「[」命令上有一個關閉「]」括號,但除「[」與「test」相同外。 「人體測試」是一件好事情閱讀。

+0

'man test'是/ bin/test的聯機幫助文件,不用於內置shell函數 – stew 2016-11-14 17:39:53

+0

'ls $(which []'給出'/ usr/bin/[' – 2017-12-26 07:08:43

5

您可以使用情況/ ESAC代替的if/else

case "$choose" in 
    [yY]) echo "Yes" && exit;; 
    [nN]) echo "No" && exit;; 
    *) echo "wrong input" && exit;; 
esac 
-2

不要使用任何保留的關鍵字作爲任何變量名的開頭: 如域名將失敗,因爲HOST {TYPE | NAME}被保留

21

在你的代碼替換該行:

#!/bin/sh 

#!/bin/bash 

這必須是腳本的第一行,並指出必須使用哪個linux外殼。 sh不支持與bash相同的命令。

+0

]這應該被標記爲正確的答案。 – MaxZoom 2017-07-28 14:42:40