2016-08-02 38 views
-1

我ENV無法使用/ bin/zsh來編譯CSHARP程序,但/斌/慶典可以

OSX 10.11.6 
zsh 5.0.8 (x86_64-apple-darwin15.0) 
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15) 
Mono C# compiler version 4.0.5.0 

test.cs中

class Test { 
     public static void Main() { 
       System.Console.WriteLine("hello, world"); 
     } 
} 

test.sh

#! /bin/bash 

mcs -recurse:*.cs 

我可以使用./test.sh編譯test.cs

但如果我將test.sh更改爲

#! /bin/zsh 

mcs -recurse:*.cs 

錯誤顯示

./test.sh:3: no matches found: -recurse:*.cs 

所以,爲什麼我不能使用的zsh?

回答

2

zsh正在嘗試將文件glob中的*作爲文件glob擴展,失敗並拋出錯誤。

bash做同樣的事情,但默認情況下,它只是忽略globbing失敗並保持單詞不變(所以mcs看到它期望的參數)。

shopt -s failglob添加到腳本的頂部(對於bash),它也會失敗。

在參數mcs中引用*以避免這種情況。

mcs -recurse:'*.cs' 
2

由於字符串-recurse:*.cs包含一個不帶引號*,大部分炮彈將嘗試把它當作一個glob模式,並將其擴展到一個或多個匹配的文件名。

zsh中的默認行爲是將沒有匹配的模式視爲錯誤,而不是將模式視爲文字字符串。如果啓用failglob選項,則可以在bash中看到相同的行爲。

$ echo foo* 
foo* 
$ shopt -s failglob 
$ echo foo* 
bash: no match: foo* 

zsh,無論引用圖案:

#! /bin/zsh 

mcs -recurse:"*.cs" 

關掉NOMATCH選項,

#! /bin/zsh 

setopt NO_NOMATCH 
mcs -recurse:*.cs 

,或者使用的zsh命令修飾符:

#! /bin/zsh 

noglob mcs -recurse:*.cs 
1

在喲ur命令mcs -recurse:*.cs,*旨在作爲參數的文字部分傳遞給mcs,但它對於所有常見的Unix shell(bash,zshtcsh等)作爲路徑名擴展的通配符也是有意義的。因此,如果工作目錄中有一個名爲-recurse:oops.cs的文件,您的命令可能會讓您感到驚訝。

當沒有文件與給定模式匹配時,shell的默認行爲會產生差異。默認情況下,bash回退,猜測您的意思是*是文字,實際上您的意思是。另一方面,由於未能與模式匹配,因此表現出更傳統的失敗行爲。 bash也可以通過打開其failglob選項來誘導展現該行爲。

最好的解決方案是通過引用參數來解決歧義,或者至少從中逃脫*bashzsh都應該可以在沒有任何特殊選項的情況下處理此版本:

mcs -recurse:\*.cs