2016-08-02 34 views
-1

Mein envKann nicht verwenden/bin/zsh ein csharp Programm zu kompilieren, aber/bin/bash kann

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 

Ich kann ./test.sh verwenden, um test.cs

zu kompilieren, aber wenn ich test.sh zu ändern

#! /bin/zsh 

mcs -recurse:*.cs 

Fehler zeigt

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

Also, warum ich nicht zsh verwenden kann?

Antwort

2

zsh versucht, die * in diesem Wort als Datei Glob, Fehler zu erweitern und einen Fehler zu werfen.

bash macht dasselbe, aber standardmäßig ignoriert es einfach den Globbing-Fehler und hält das Wort intakt (so sieht mcs das Argument, das es erwartet).

Fügen Sie shopt -s failglob an den Anfang des Skripts (für bash) und es wird auch fehlschlagen.

Zitieren Sie die * im Argument zu mcs, um dies zu vermeiden.

mcs -recurse:'*.cs' 
2

Da die Zeichenfolge -recurse:*.cs ein nicht notiert * enthält, werden die meisten Schalen versuchen, es als ein glob Muster zu behandeln und erweitern es um einen oder mehr passenden Dateinamen.

Das Standardverhalten in zsh besteht darin, ein Muster, das keine Übereinstimmungen aufweist, als Fehler zu behandeln, anstatt das Muster als Literalzeichenfolge zu behandeln. Dasselbe Verhalten kann in bash angezeigt werden, wenn Sie die Option failglob aktivieren.

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

In zsh entweder zitieren das Muster:

#! /bin/zsh 

mcs -recurse:"*.cs" 

Abzweigung der NOMATCH Option,

#! /bin/zsh 

setopt NO_NOMATCH 
mcs -recurse:*.cs 

oder verwenden Sie den zsh Befehlsmodifizierers:

#! /bin/zsh 

noglob mcs -recurse:*.cs 
1

In yo Ihr Befehl mcs -recurse:*.cs, der * soll an mcs als ein wörtlicher Teil des Arguments weitergegeben werden, aber es ist auch für alle gängigen Unix-Shells (bash, zsh, tcsh und andere) als Platzhalter für die Pfadnamenerweiterung sinnvoll. Daher würde Ihr Befehl Sie wahrscheinlich überraschen, wenn sich im Arbeitsverzeichnis eine Datei mit dem Namen -recurse:oops.cs befindet.

Der Unterschied tritt im Standardverhalten der Shells auf, wenn keine Datei dem angegebenen Muster entspricht. Standardmäßig geht bash darauf zurück zu erraten, dass Sie die * als ein Literal verstanden haben, was in der Tat das ist, was Sie meinten. zsh zeigt andererseits das traditionellere Verhalten des Versagens aufgrund des Nichtanpassens des Musters. bash kann auch induziert werden, um dieses Verhalten zu zeigen, indem man seine failglob Option aktiviert.

Die beste Lösung besteht darin, die Mehrdeutigkeit aufzulösen, indem Sie das Argument zitieren oder zumindest die * darin entziehen. Sowohl bash als auch zsh sollten mit dieser Version gut ohne spezielle Optionen umgehen:

mcs -recurse:\*.cs