Ich wechsle von einem langjährigen tcsh-Benutzer zu einem neuen Bash-Benutzer (es ist weit überfällig). Ich habe regelmäßig viele foreach-Schleifen in tcsh on the fly geschrieben, daher habe ich die Syntax für Bashs für Schleifen als Ersatz gelernt, war aber überrascht, als nicht übereinstimmende Glob-Muster als wörtliche Zeichenfolgen durch die Schleife geleitet wurden. Ich suchte nach einer Möglichkeit, dieses Verhalten so zu ändern, dass wörtliche Zeichenfolgen übersprungen und gefunden werden shopt -s nullglob
. Mein Verständnis war, dass dies theoretisch dem Verhalten von tcsh entsprechen sollte, aber heute habe ich einen Unterschied entdeckt. Wenn ich das tue ls ../*.doesnotmatch
, war das Ergebnis eine Liste des Inhalts des aktuellen Verzeichnisses. Insbesondere habe ich dies getan:
Bash:
$ shopt -s nullglob
$ ls ../*.sam
extractSplitReads_BwaMem extractSplitReads_BwaMem.xml
$ shopt -u nullglob
$ ls ../*.sam
ls: ../*.sam: No such file or directory
Es gibt nichts im übergeordneten Verzeichnis, was übereinstimmt *.sam
, insbesondere nicht das aktuelle Verzeichnis. Zuerst war ich wirklich verwirrt, aber dann wurde mir klar, dass das Glob-Muster verschwindet und der Befehl ausgeführt wurde, als hätte ich keine Argumente angegeben, z.
$ ls
Also habe ich versucht, Failglob sowohl für sich als auch mit Nullglob zu setzen, aber solange Failglob gesetzt ist, bricht jedes nicht übereinstimmende Glob-Muster den Befehl ab, unabhängig davon, ob ein übereinstimmendes Muster vorhanden ist oder nicht:
Bash:
$ shopt -s failglob
$ shopt -s nullglob
$ ls ../vis*/*.xml
../visualization/LAJ.xml
$ ls ../vis*/*.xml ../*.sam
bash: no match: ../*.sam
$ ls ../{vis*/*.xml,*.sam}
bash: no match: ../*.sam
Wenn ich tcsh verwende, werden alle Globs auf die übereinstimmenden Elemente reduziert. Wenn nichts übereinstimmt, wird ein Glob-Fehler angezeigt:
tcsh:
$ ls ../vis*/*.xml ../*.sam
../visualization/LAJ.xml
$ ls ../{vis*/*.xml,*.sam}
../visualization/LAJ.xml
$ ls ../*.sam
ls: No match.
Ich habe die Shopt-Einstellungen durchgesehen, sehe aber keinen Weg, um dieses Verhalten zu erreichen. Vermisse ich etwas Gibt es neben bash oder tcsh noch eine andere moderne Shell, die Globs so behandelt wie tcsh? Ich möchte das Verhalten von nullglob, wenn etwas übereinstimmt, aber das Verhalten von failglob, wenn nichts übereinstimmt, wie tcsh anscheinend funktioniert.
zsh
statt zu gehenbash
wäre ein viel natürlicherer Übergang.zsh
Globs funktionierenbash -O failglob
standardmäßig wie , aber Sie können diecshnullglob
Option verwenden, damit sie sich wie verhälttcsh
. Siehe auch Warum ist nullglob nicht standardmäßig?Antworten:
Die einzigen
shopt
Optionen im Zusammenhang mit Dateinamen Expansion sinddotglob
,failglob
,nocaseglob
undnullglob
, und keiner von ihnen (allein oder kombiniert) scheint genau das zu tun , was Sie wollen. Es ist eine Schande, denn das klingt nach einer wirklich guten Idee.Meine Empfehlung ist,
failglob
in interaktiven Sitzungen festgelegt zu haben, damit Sie potenziell unerwünschte Befehle vermeiden können, wie z.wo
file1
,file2
unddir1
würde verschoben werden,dir2
wenndestination-*-dir
nichts übereinstimmt undnullglob
gesetzt ist.Auf der anderen Seite ist es keine gute Idee, sich beim Shell-Scripting vollständig auf Dateinamenerweiterungen zu verlassen. Es ist empfehlenswert, immer zu überprüfen, ob solche Erweiterungen vorhanden sind und wie sie sein sollen.
Ich meine, anstatt dies zu tun:
Es ist besser, so etwas zu tun:
Auf diese Weise sind Sie sicher, auch wenn beispielsweise einige Dateien übereinstimmen
*.txt
, es sich jedoch tatsächlich um ein Verzeichnis handelt.quelle