不能使用/ bin / zsh编译csharp程序,但/ bin / bash可以

时间:2016-08-02 17:28:09

标签: c# bash mono zsh gmcs

我的环境

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?

3 个答案:

答案 0 :(得分:2)

zsh正试图将该单词中的*扩展为文件glob,失败并抛出错误。

bash执行相同的操作,但默认情况下,它只是忽略了全局失败并保持单词完整(所以mcs看到了它所期望的参数)。

shopt -s failglob添加到脚本顶部(bash),它也会失败。

引用*参数中的mcs以避免这种情况。

mcs -recurse:'*.cs'

答案 1 :(得分:2)

因为字符串-recurse:*.cs包含不带引号的*,所以大多数shell会尝试将其视为glob模式并将其扩展为一个或多个匹配的文件名。

zsh中的默认行为是将没有匹配的模式视为错误,而不是将模式视为文字字符串。如果您启用bash选项,则可以在failglob中看到相同的行为。

$ 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

答案 2 :(得分:1)

在您的命令mcs -recurse:*.cs中,*旨在作为参数的文字部分传递给mcs,但它对所有常见的Unix shell也有意义({{ 1}},bashzsh和其他)作为路径名扩展的通配符。因此,如果工作目录中有一个名为tcsh的文件,您的命令可能会让您感到惊讶。

贝壳中出现了差异。没有文件与给定模式匹配时的默认行为。默认情况下,-recurse:oops.cs会回到猜测你的意思是bash是文字,这实际上就是你的意思。另一方面,*表现出由于未能匹配模式而导致失败的更传统行为。通过启用zsh选项,bash也可以被诱导表现出这种行为。

最好的解决方案是通过引用参数来解决歧义,或至少转义其中的failglob*bash都应该处理此版本,没有任何特殊选项:

zsh
相关问题