staging.inyokaproject.org

Seltsames Verhalten beim Globbing

Status: Gelöst | Ubuntu-Version: Ubuntu 22.04 (Jammy Jellyfish)
Antworten |

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4212

Hallo,

ich bereite gerade eine Schulung in Bezug auf Globbing vor und kann mir gerade ein Verhalten der Bash nicht so richtig erklären. Man nehme folgende Befehle:

doc@x1 ~  $ mkdir testdir 
doc@x1 ~  $ cd testdir
doc@x1 ~/testdir  $ echo test{1,2}*.txt
test1*.txt test2*.txt
doc@x1 ~/testdir  $ touch test1.txt
doc@x1 ~/testdir  $ echo test{1,2}*.txt
test1.txt test2*.txt

Das Ergebnis des letzten Befehls kann ich mir nicht so richtig erklären.

Also das "test{1,2}*.txt" wird ja erstmal expandiert nach "test1*.txt test2*.txt".

Aber da scheint ja noch ein Matching auf existierende Dateien zu erfolgen. Aber warum wird dann "test2*.txt" noch ausgegeben, obwohl keine Datei existiert, auf die dieses Pattern passt?

Also ich hätte da als Ausgabe entweder (kein Matching auf existierende Dateien)

test1*.txt test2*.txt

oder (Matching auf existierende Dateien)

test1.txt

erwartet.

Kann mir da jemand auf die Sprünge helfen?

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7529

Na ja das sind eben 2 Schritte.

Zuerst { } Brace Expansion und danach * Pathname Expansion / Pattern Matching

Und beim * ist es so, das der String 1:1 ausgegeben wird, wenn keine Datei passt. Wenn du das nicht willst kannst du shopt -s nullglob setzen.

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 7816

Doc_Symbiosis schrieb:

Aber warum wird dann "test2*.txt" noch ausgegeben, obwohl keine Datei existiert, auf die dieses Pattern passt?

Du hast zwei Muster angegeben. Auf das erste passt ein Dateiname, also wird dieser ausgegeben. Auf das zweite Muster (test2*.txt) passt kein existierender Dateiname, also wird das Muster selbst ausgegeben.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

Eigentlich haben meine Vorredner schon alles erklärt. Ich schicke die Nachricht trotzdem ab; vielleicht ist ja das Beispiel hilfreich.

Doc_Symbiosis schrieb:

Das Ergebnis des letzten Befehls kann ich mir nicht so richtig erklären.

Also das "test{1,2}*.txt" wird ja erstmal expandiert nach "test1*.txt test2*.txt".

Ja.

Aber da scheint ja noch ein Matching auf existierende Dateien zu erfolgen.

Nein. Das ist nicht der Fall: Es gibt ja keine Datei.

Aber warum wird dann "test2*.txt" noch ausgegeben, obwohl keine Datei existiert, auf die dieses Pattern passt?

Die Muster werden nach POSIX-Standard zu sich selbst expandiert, wenn keine passende Datei gefunden wird. Das Verhalten kann man in der bash ändern durch das Setzen der Option "nullglob".

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$ ls -l
total 0
$ shopt nullglob 
nullglob       	off
$ echo foo*.txt
foo*.txt
$ touch foobar.txt
$ echo foo*.txt
foobar.txt
$ rm foobar.txt 
$ shopt -s nullglob
$ echo foo*.txt

$ for f in *; do echo "> $f"; done
$ shopt -u nullglob
$ for f in *; do echo "> $f"; done
> *

Doc_Symbiosis

(Themenstarter)
Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4212

Cool, ganz herzlichen Dank für eure ganzen Hinweise!

Mir war einfach nicht klar, dass das Muster einfach erhalten bleibt, wenn keine passende Datei gefunden wird (natrülich nur, sofern nullglob nicht an ist).

Wieder was gelernt!

Antworten |