[英]Can not use /bin/zsh to compile a csharp program, but /bin/bash can
My env 我的环境
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 test.cs
class Test {
public static void Main() {
System.Console.WriteLine("hello, world");
}
}
test.sh test.sh
#! /bin/bash
mcs -recurse:*.cs
I can use ./test.sh to compile test.cs 我可以使用./test.sh来编译test.cs
but if I change test.sh to 但是如果我将test.sh更改为
#! /bin/zsh
mcs -recurse:*.cs
error shows 错误显示
./test.sh:3: no matches found: -recurse:*.cs
So, Why I can not use zsh? 那么,为什么我不能使用zsh?
zsh
is attempting to expand the *
in that word as a file glob, failing, and throwing an error. zsh
尝试将该单词中的*
扩展为文件glob,失败并引发错误。
bash
does the same thing but, by default, it just ignores the globbing failure and keeps the word intact (so mcs
sees the argument it expects). bash
做同样的事情,但是默认情况下,它只是忽略了globbing失败并保持单词完整(因此mcs
看到了它期望的参数)。
Add shopt -s failglob
to the top of the script (for bash
) and it will fail also. 将shopt -s failglob
添加到脚本顶部(对于bash
),它也会失败。
Quote the *
in the argument to mcs
to avoid this. 为了避免这种情况,请在mcs
的参数中引用*
。
mcs -recurse:'*.cs'
Because the string -recurse:*.cs
contains an unquoted *
, most shells will attempt to treat it as a glob pattern and expand it to one or more matching file names. 因为字符串-recurse:*.cs
包含未加引号的*
,所以大多数shell都会尝试将其视为glob模式并将其扩展为一个或多个匹配的文件名。
The default behavior in zsh
is to treat a pattern that has no matches as an error, rather than treating the pattern as a literal string. zsh
的默认行为是将没有匹配项的模式视为错误,而不是将模式视为文字字符串。 The same behavior can be seen in bash
if you enable the failglob
option. 如果启用failglob
选项,则在bash
可以看到相同的行为。
$ echo foo*
foo*
$ shopt -s failglob
$ echo foo*
bash: no match: foo*
In zsh
, either quote the pattern: 在zsh
,要么引用模式:
#! /bin/zsh
mcs -recurse:"*.cs"
turn off the NOMATCH
option, 关闭NOMATCH
选项,
#! /bin/zsh
setopt NO_NOMATCH
mcs -recurse:*.cs
or use the zsh command modifier: 或使用zsh命令修饰符:
#! /bin/zsh
noglob mcs -recurse:*.cs
In your command mcs -recurse:*.cs
, the *
is intended to be passed to mcs
as a literal part of the argument, but it is also meaningful to all common Unix shells ( bash
, zsh
, tcsh
, and others) as a wildcard for pathname expansion. 在您的命令mcs -recurse:*.cs
, *
旨在作为参数的文字部分传递给mcs
,但对于所有常见的Unix shell( bash
, zsh
, tcsh
和其他),它也有意义。通配符,用于路径名扩展。 As such, your command would probably surprise you if there were a file named -recurse:oops.cs
in the working directory. 这样,如果工作目录中有一个名为-recurse:oops.cs
的文件,则您的命令可能会使您感到惊讶。
The difference arises in the shells' default behavior when no file matches the given pattern. 当没有文件与给定模式匹配时,shell的默认行为会有所不同。 By default, bash
falls back to guessing that you meant the *
to be a literal, which is in fact what you meant. 默认情况下, bash
会猜测您将*
表示为文字,这实际上是您的意思。 zsh
, on the other hand, exhibits the more traditional behavior of failing on account of the failure to match the pattern. 另一方面, zsh
表现出更传统的失败行为,即由于无法匹配模式而导致失败。 bash
can be induced to exhibit that behavior, too, by turning on its failglob
option. 通过打开failglob
选项, bash
也可以表现出这种行为。
The best solution is to resolve the ambiguity by quoting the argument, or at least escaping the *
in it. 最好的解决方案是通过引用参数或至少转义其中的*
来解决歧义。 Both bash
and zsh
should handle this version fine without any special options: bash
和zsh
都应该可以很好地处理此版本,而无需任何特殊选项:
mcs -recurse:\*.cs
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.