Wer beschäftigt sich mit dem Stern * im Echo *

6859
faressoft

Wer behandelt das * in

echo * 

Kann das Echo den Stern oder die Shell erkennen und eine Liste mit Dateinamen zurückgeben?

Wie wäre es mit

cp temp temp* 
15
Es variiert. Unix-Shells oder Windows-Shells? grawity vor 9 Jahren 14
@Grawity Unix-Shells. Entschuldigung, dass ich das nicht erwähnt habe. faressoft vor 9 Jahren 0
Für Unix sind die folgenden Antworten richtig. (Unter Windows erfolgt dies durch einzelne Programme - normalerweise jedoch automatisch durch die Laufzeitbibliothek vor main ().) grawity vor 9 Jahren 0

4 Antworten auf die Frage

24
Jarmund

bash (oder was auch immer Sie als Shell verwenden) liest zuerst alle Eingaben und beginnt, Sonderzeichen wie ?und zu interpretieren *. *wird auf alle Übereinstimmungen in der CWD erweitert, was bedeutet, dass der Stern durch die Übereinstimmungen ersetzt wird.

In den meisten Fällen ist dies ein wenig nach vorne gerichtet, kann jedoch gelegentlich zu einigen verwirrenden Fällen führen.

Folgendes berücksichtigen. Ein Verzeichnis hat diesen Inhalt:

  • Test (reguläre Datei)
  • test1 (verzeichnis)
  • test2 (verzeichnis)
  • test3 (verzeichnis)

Wenn Sie dann mv *etwas tippen, passiert ein scheinbar seltsames Ereignis: Ist test3dort, aber der Rest ist weg. Obwohl es zunächst seltsam ist, macht es Sinn, wenn Sie erst einmal verstanden haben, worauf sich bash tatsächlich bezieht mv. Aufgrund des Sterns interpretiert bash das mv *als mv test test1 test2 test3, und wenn mv diese Liste erhält, wird davon ausgegangen, dass das letzte Argument das Ziel ist, in das alle Dateien verschoben worden wären.

Für die Befehle, die Sie aufgelistet haben:

  • echo *kann als armes mans funktionieren ls. Die Shell wird das Sternchen auf das erweitern, was sich in diesem Verzeichnis befindet, und wie ich sicher weiß, dass Sie es bereits wissen, echowird es buchstäblich alles widerhallen, was als Bash an ihn übergeben wird.
  • cp temp temp*verhält sich etwas wie der mvBefehl, den ich oben beschrieben habe, es sei denn, es gibt nur ein Verzeichnis mit dem Namen temp. In diesem Fall sind Quell- und Zielname identisch, dh es wird nichts ausgeführt.
Es ist nichts "schlecht", wenn Sie "*" anstelle von "ls" verwenden. Zum Beispiel `für f in *; do` ist * zuverlässiger als `for f in $ (ls)`, wenn ein Dateiname Leerzeichen oder ein Glob-Zeichen enthält. (Wenn jedoch keine Dateien in der CWD vorhanden sind, schlägt dies fehl, daher müssen Sie nach diesem Fall suchen.) rici vor 9 Jahren 8
@rici Dafür gibt es `shopt nullglob`. a CVn vor 9 Jahren 1
In Bezug auf `echo *` kann dieser Trick in manchen Fällen (http://www.ee.ryerson.ca/~elf/hack/recovery.html) gespeichert werden. a CVn vor 9 Jahren 3
@ MichaelKjörling Kann es, und es hat mich sicherlich mindestens einmal gerettet. Jarmund vor 9 Jahren 0
@ MichaelKjörling: Ja, das ist eine Möglichkeit. Die Einstellung dieser Option global hat jedoch oft auch unglückliche Konsequenzen. Möglicherweise möchten Sie eine Fehlermeldung ausgeben. In der Regel ist es jedoch so, dass eine Fehlermeldung der Form "the_directory / *" nicht geöffnet werden kann. rici vor 9 Jahren 0
Abgleich mit: Dateien mit vorangestelltem "-" in beliebigen Ordnern, die unerwünschte Schalter auslösen. Sie zu entfernen macht keinen großen Spaß, bis Sie feststellen, dass die Datei rm ./-stupidfile funktioniert. ǝɲǝɲbρɯͽ vor 9 Jahren 2
@ ǝɲǝɲbρɯͽ Ich habe bemerkt, als ich einmal den Inhalt eines Verzeichnisses löschen musste, das Dateien enthält, deren Dateiname Positionen in einem Koordinatensystem darstellt, von -1024x-1024 bis 1024x1024. Da habe ich zum ersten Mal von Flucht erfahren. Jarmund vor 9 Jahren 1
Ich glaube, ich muss meine auffrischen. "mv" gibt nicht die gleichen Hinweise wie "rm", also durchläuft ich die Tab-Vervollständigung, \ - \ - \ - sf = nicht erkannte Option (dasselbe ohne Escaping), \\ - keine solche Datei. Zitat hat nicht funktioniert, ich habe ein paar andere Sachen ausprobiert und schließlich rm angedeutet. Ich schätzte das sehr, weil ich verdammt war, wenn ich mit dem Gui betrügen würde (woher es kam). ǝɲǝɲbρɯͽ vor 9 Jahren 0
5
jlliagre

Wie bereits erwähnt, dehnt sich die Schale *so echoals Argumente erhalten, was die Shell im aktuellen Verzeichnis finden. Beachten Sie jedoch Folgendes: Wenn die Erweiterung zu nichts führt, dh wenn das Verzeichnis keine nicht verborgenen Dateien enthält, *bleibt das unverändert und wird unverändert an den aufgerufenen Befehl übergeben (es sei denn, bei einigen Shells werden nicht standardmäßige Optionen verwendet bash.) echo *wird sich dann nicht wie ein armer Mann verhalten, lsda der erstere nichts druckt, während der letztere druckt *.

Ebenso cp /tmp/temp temp*wird temp*im aktuellen Verzeichnis eine Datei erstellt, wenn noch nicht mindestens eine Datei mit dem Namen beginnt temp.

Wenn Sie möchten *, dass die Datei in jedem Fall unverändert übergeben wird, können Sie sie entweder durch einfache Anführungszeichen '*', doppelte Anführungszeichen "*"oder umgekehrten Schrägstrich vor der Erweiterung schützen \*.

4
barlop

In Bash beschäftigt sich die Hülle damit. Sie sehen das, wenn Sie es sogar *ohne Echo versuchen

Hinweis: Basierend auf einigen Kommentaren würde ich beim Ausführen von * ENTER vorschlagen, ein Verzeichnis zu erstellen und den Befehl touch zu verwenden, um einige Dateien zu erstellen und sicherzustellen, dass keine oder zumindest die erste alphabetisch nicht der Name ist eines Skripts oder Befehls im Pfad.

$ * bash: a: command not found  $ echo * a a.aa a.ab a.b a.htm a.tx 

Ist ls *also ein bisschen ein Klischee

In Windows *wird mit dem Befehl dir *.*gehandelt, also kein Klischee.

Anmerkung: Wenn ich einige Kommentare sehe, würde ich hinzufügen, dass ein Risiko besteht, * und dann ENTER. Wenn Sie eine Datei namens rm haben, die sich zuerst in der Verzeichnisliste befindet, ist dies gefährlich, da alles, was danach geschrieben wird, gelöscht wird. Und dies ist auch weniger unwahrscheinlich. Wenn die erste Datei in der Verzeichnisliste der Name eines Skripts im Pfad ist, wird diese ausgeführt.

Beachten Sie, dass es natürlich eine Datei mit dem Namen "rm" geben kann. Volker Siegel vor 9 Jahren 4
... und noch einer namens -rf ǝɲǝɲbρɯͽ vor 9 Jahren 1
@ ǝɲǝɲbρɯͽ Kannst du eine Datei mit dem Dateinamen `-rf` haben? Ich habe `touch -rf` und` touch \ -rf` ausprobiert, aber es wird nicht erstellt. barlop vor 9 Jahren 1
@barlop habe ich oben kommentiert; das gui (wie gedit) behandelt sie gut, aber da die shell (zumindest bash) dies durchläuft, ist ./ vorne. Sollten Sie versehentlich eine solche Datei erstellen, versucht rm einen Hinweis, aber wenn nicht: Ich hoffe, dass dies nur in einem temporären Ordner mit Einwegkindern endet. ǝɲǝɲbρɯͽ vor 9 Jahren 0
@ ǝɲǝɲbρɯͽ Ich verstehe nicht was du meinst, ich frage mich, wie du eine Datei erstellen kannst, die `-rf` heißt. (Ich verstehe die Gefahr einer Datei namens rm und einer Datei namens -rf, und das Problem, dass Sie * eingeben und die Eingabetaste in einem wichtigen Ordner drücken. Ich habe nicht vor, das zu tun.) barlop vor 9 Jahren 0
@barlop In einem Kommentar zu Jarmunds Antwort: rm ./-stupidfile (was bedeutet, dass - ein Ärgernis ist). Berühren Sie hier ./-rf. Angenommen, Sie verwenden Gnome unter Linux, speichert gedit eine Datei namens -anyfile ohne Probleme. Rm -anyfile schlägt jedoch fehl und warnt Sie möglicherweise "Vielleicht wollten Sie rm ./-anyfile?" Ich glaube, die Shell wird angewiesen, eine Datei am aktuellen Speicherort (.) zu suchen, anstatt sie als Schalter für den Parameter-Stream zu betrachten. Diese Warnung kann von der Shell abhängen. Da wir die Frage zwar meta, aber nicht Ihre Antwort haben, macht es mir nichts aus, im Chat nachzufragen. ǝɲǝɲbρɯͽ vor 9 Jahren 0
@ ǝɲǝɲbρɯͽ soll einen Chat-Link erzeugen, wenn die Kommentare lang werden. Und gibt die Option, sie zu importieren. Ja, ich sehe Berührung ./-rf funktioniert, obwohl * die alphabetische Reihenfolge erweitern würde, -rf vor rm, es konnte rm -rf nicht ausführen. barlop vor 9 Jahren 0
Lassen Sie uns [diese Diskussion im Chat fortsetzen] (http://chat.stackexchange.com/rooms/22871/discussion-between-barlop-and-eebm). barlop vor 9 Jahren 0
-1
glenn jackman
Technisch ist das, was Sie schreiben, korrekt, aber ohne die Links kann diese Antwort die Frage nicht wirklich beantworten. Berücksichtigen Sie die Einbeziehung der relevanten Details. a CVn vor 9 Jahren 0
@ MichaelKjörling Ich bin mit der Sache über die Links einverstanden, aber das OP hat einfach gefragt, ob die Shell oder der Befehl selbst die Argumente gehandhabt hat. Glenns Antwort besagt lediglich, dass die Shell mit ihnen umgeht, also eine akzeptable Antwort auf die Frage. slhck vor 9 Jahren 0
@slhck Aus diesem Grund habe ich nicht als NAA gekennzeichnet: Es gibt * etwas *, das die Frage beantwortet, nachdem die Links entfernt wurden. Das bedeutet nicht, dass dies meiner Meinung nach eine * gute * Antwort ist. (Ich sehe jetzt, dass mein ursprünglicher Kommentar anders ausgelegt werden könnte; dafür entschuldige ich mich, aber ich denke immer noch, dass er genug Wert hat, um ihn dort zu lassen, wo er ist.) a CVn vor 9 Jahren 0
@ MichaelKjörling Einverstanden. Ich habe nur den Kommentar für diejenigen hinterlassen, die ihn als NAA gekennzeichnet haben (und werden). slhck vor 9 Jahren 0