Controlling-shell-Befehlszeile wildcard-Erweiterung in C oder C++
Ich Schreibe ein Programm, foo, in C++. Es ist in der Regel aufgerufen, auf der Kommando-Zeile wie diese:
foo *.txt
Meine main()
erhält die Argumente, die in der üblichen Weise. Auf vielen Systemen argv[1]
ist buchstäblich *.txt
, und ich habe das aufrufen von system-Routinen zu tun, die wildcard-Erweiterung. Auf Unix-Systemen, allerdings ist die shell erweitert den wildcard vor dem Aufruf von meinem Programm, und alle übereinstimmenden Dateinamen werden in argv
.
Angenommen, ich wollte einen Schalter hinzufügen, um "foo", die bewirkt, dass es zu Rekursion in Unterverzeichnisse.
foo -a *.txt
verarbeitet alle Textdateien im aktuellen Verzeichnis und alle seine Unterverzeichnisse.
Ich sehe nicht, wie dies geschehen ist, da, durch die Zeit, die mein Programm bekommt eine chance zu sehen, die -a
, dann hat shell bereits fertig, der ausbau und die Benutzer *.txt
Eingabe ist verloren. Dennoch gibt es gemeinsame Unix-Programme, die funktionieren auf diese Weise. Wie tun Sie es?
In Unix land, wie kann ich das wildcard-expansion?
(Recursing durch Unterverzeichnisse ist nur ein Beispiel. Im Idealfall, ich versuche zu verstehen, die Allgemeine Lösung für die Kontrolle der wildcard-expansion.)
- BTW--shell-Jokerzeichen genannt "Einheiten" und dass die Funktionalität erhalten werden kann programmgesteuert mithilfe
glob (3)
.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du das Programm hat keinen Einfluss auf die shell-Befehlszeilen-expansion. Welches Programm aufgerufen wird, wird bestimmt, nachdem alle der ausbau fertig ist, so ist es bereits zu spät, etwas zu ändern über die Erweiterung programmgesteuert.
Der Anwender ruft das Programm ein, auf der anderen Seite, hat die Möglichkeit alles zu erschaffen, was Befehlszeile, die er mag. Schalen können Sie leicht verhindern, dass wildcard-expansion, in der Regel, indem das argument in einfache Anführungszeichen gesetzt:
Wenn Ihr Programm wird so aufgerufen wird, erhält zwei Parameter
-a
und*.txt
.Auf Unix, sollten Sie nur lassen Sie es an die Benutzer manuell zu verhindern, wenn wildcard-Erweiterung nicht gewünscht ist.
.orig
Dateien in das aktuelle Arbeitsverzeichnis. Ihre shell-wahrscheinlich hält die*.orig
etwa wörtlich, wenn (und nur wenn) es sind nicht irgendwelche Spiele (die bash das auch tut, wenn dienullglob
shell-option ist nicht gesetzt).echo
ist ein gutes Programm, um zu testen, wie sich die Dinge.Als die anderen Antworten gesagt, die shell hat die wildcard-expansion - und Sie aufhören, es zu tun, so dass Argumente in Anführungszeichen.
Beachten Sie, dass Optionen
-R
und-r
sind in der Regel verwendet, um anzuzeigen, rekursive, siehecp
,ls
usw Beispiele.Vorausgesetzt, Sie organisieren Dinge entsprechend, so dass die Platzhalter übergeben werden, um Ihr Programm als Platzhalter und du willst Rekursion, dann POSIX stellt Routinen zu helfen:
nftw
- Datei-tree-walk (rekursiven Zugriff).fnmatch
,glob
,wordexp
- zu tun mit dem Namen matching-und ausbauGibt es auch
ftw
, die sehr ähnlich zunftw
aber es ist markiert mit 'veralteten', also neuen code sollten Sie nicht verwenden.Adrian fragte:
Anpassung der Frage an einem geeigneten Ort auf meinem computer, lassen Sie uns überprüfen:
So, ich habe eine sub-directory 'mte', der drei Dateien enthält. Und ich habe sechs Dateien mit Namen, die beginnen 'm'.
Geben, wenn ich 'ls -R1 m*' die shell nimmt die Metazeichen '*' und nutzt seine Entsprechung
glob()
oderwordexp()
zu erweitern, dass in der Liste der Namen:Dann die shell ordnet ausführen '
/bin/ls
' mit 9 Argumenten (Programm-name, option-R1
plus 7 Datei-Namen und abschließenden null-Zeiger).ls
Befehl Hinweise die Optionen (rekursive und single-Spalte-Ausgabe), und macht sich an die Arbeit.ls
gibt seinen Namen und seinen Inhalt, Aufruf seine Entsprechungnftw()
um die Arbeit zu tun.ls
Prozesse die nicht-Verzeichnis-Namen zuerst, und verarbeitet dann die Verzeichnis-Namen in alphabetischer Reihenfolge (standardmäßig), und hat eine Tiefe-zuerst-scan von jedem Verzeichnis.ls -R *.txt
ohne Anführungszeichen und erhalten Sie eine rekursive Liste. Wie funktioniert das? (Und, ja, ich weiß-R
und-r
sind die üblichen Auswahlmöglichkeiten für die Anzeige einer rekursiven Abstieg. Ich habe absichtlich verwendet einen anderen Buchstaben zu vermeiden, dass Antworten, die waren zu speziell sind, um das problem.)-R
option " ls " und eine wildcard hat nicht geben Sie eine rekursive Liste aller Dateien, die passenden Muster.ls -R *.txt
' nicht darauf beschränken, die aufgelisteten Dateien, um diese Namen zu Ende '.txt'.-R
Optionen gilt für die gesamtels
Befehl. Damit die shell erweitert den wildcard und dannls
rekursiv Listen alle der Parameter. Versuchen Siels -R dir1.txt dir2.txt
(oder was auch immer, sind die entsprechenden Namen) zu sehen, dass.Teil der shell, der job (auf Unix) ist zu erweitern Befehlszeilen-Platzhalter Argumente. Verhindern Sie, dass Sie diese mit Anführungszeichen.
Auch auf Unix-Systemen, die "find" - Befehl tut, was Sie wollen:
Liste aller Dateien rekursiv ab dem aktuellen Verzeichnis nach unten.
So, könnten Sie tun,
Wollte ich darauf hinweisen, einen anderen Weg zu deaktivieren wildcard-expansion. Sie können sagen, dass Ihre shell zu stoppen expandierende wildcards, mit der die
noglob
option.Mit bash verwenden
set -o noglob
:Und mit csh verwenden
set noglob
: