Frage

Zusätzlich zu den grundlegenden *, ? und [...] Muster stellt die Schlag-Shell verlängerte Muster Operatoren wie !(pattern-list) Matching ( „mit einer Ausnahme der gegebenen Muster alle Ergebnisse“). Die extglob Shell Option muss eingestellt werden, um sie zu verwenden. Ein Beispiel:

~$ mkdir test ; cd test ; touch file1 file2 file3
~/test$ echo *
file1 file2 file3
~/test$ shopt -s extglob  # make sure extglob is set
~/test$ echo !(file2)
file1 file3

Wenn ich eine Shell-Expression zu einem Programm übergeben, die es in einer Unterschale ausgeführt wird, bewirkt, dass der Bediener einen Fehler. Hier ist ein Test, der läuft eine Unterschale direkt (hier habe ich aus einem anderen Verzeichnis bin Ausführung sicher Expansion machen geschieht nicht vorzeitig):

~/test$ cd ..
~$ bash -c "cd test ; echo *"
file1 file2 file3
~$ bash -c "cd test ; echo !(file2)"  # expected output: file1 file3
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'

Ich habe alle Arten von entkommen versucht, aber nichts, was ich mit richtig gearbeitet habe kommen hat. Ich habe auch im Verdacht extglob ist nicht in einer Unterschale gesetzt, aber das ist nicht der Fall:

~$ bash -c "shopt -s extglob ; cd test ; echo !(file2)"
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'

Jede Lösung geschätzt!

War es hilfreich?

Lösung

$ bash -O extglob -c 'echo !(file2)'
file1 file3

Andere Tipps

bash analysiert jede Zeile, bevor sie ausgeführt wird, so „shopt es extglob“ nicht wirksam sind, wenn bash die Globbing Muster-Syntax zu validieren. Die Option kann nicht auf der gleichen Linie aktiviert werden. Deshalb ist die "bash -O extglob -c 'xyz'" Lösung (von Randy Proctor) arbeitet und erforderlich ist.

Hier ist eine andere Art und Weise, wenn Sie eval vermeiden wollen, und Sie müssen drehen können extglob ein und aus in der Subshell. setzen Sie Ihre Muster nur in einer Variablen:

bash -c 'shopt -s extglob; cd test; patt="!(file2)"; echo $patt; shopt -u extglob; echo $patt'

gibt die folgende Ausgabe:

file1 file3
!(file2)

Demonstrieren, dass extglob wurde geschärft und entschärft. Wenn die erste echo Anführungszeichen um den $patt hätte, wäre es nur das Muster wie die zweite echo ausspucken (was wahrscheinlich sollte zitiert haben).

Nun, ich habe keine wirkliche experince mit extglob , aber ich kann es durch Wickeln des echo in einem eval zu arbeiten:

$ bash -c 'shopt -s extglob ; cd  test ; eval "echo !(file2)"'
file1 file3
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top