@ Grawity Unix-Shells. Entschuldigung, das habe ich nicht erwähnt.
Faressoft
Für Unix sind die folgenden Antworten korrekt. (Unter Windows wird dies von einzelnen Programmen ausgeführt - in der Regel jedoch automatisch von der Laufzeitbibliothek vor main ().)
user1686
Antworten:
24
bash (oder was auch immer Sie als Shell verwenden) ist das erste, was Sie lesen, und beginnt mit der Interpretation von Sonderzeichen wie ?und *. *wird auf alle Übereinstimmungen in der CWD erweitert , was bedeutet, dass der Stern durch diese Übereinstimmungen ersetzt wird.
In den meisten Fällen ist dies recht unübersichtlich, kann jedoch von Zeit zu Zeit zu verwirrenden Fällen führen.
Folgendes berücksichtigen. Ein Verzeichnis hat diesen Inhalt:
Test (reguläre Datei)
test1 (verzeichnis)
test2 (verzeichnis)
test3 (verzeichnis)
Wenn du dann mv *etwas scheinbar Seltsames eingibst, passiert: test3ist da, aber der Rest ist weg. Obwohl es anfangs seltsam ist, macht es Sinn, wenn Sie erst einmal verstanden haben, an was die Bash tatsächlich geht mv. Aufgrund des Sterns interpretiert Bash mv *als mv test test1 test2 test3und wenn MV diese Liste erhält, wird davon ausgegangen, dass das letzte Argument das Ziel ist, an das alle Dateien verschoben worden wären.
Wie für die Befehle, die Sie aufgelistet haben:
echo *kann als ein Armenmann funktionieren ls. Die Shell erweitert den Stern auf das, was sich in diesem Verzeichnis befindet, und gibt, wie Sie sicher bereits wissen, echobuchstäblich alle Bashs aus, die ihr als Argumente übergeben wurden.
cp temp temp*verhält sich ähnlich wie der mvoben beschriebene Befehl, es sei denn, es gibt nur ein Verzeichnis mit dem Namen temp. In diesem Fall sind Quell- und Zielname identisch, dh es wird nichts unternommen.
Es gibt nichts "Schlechtes" an der Verwendung *statt ls. Zum Beispiel for f in *; doist mehr zuverlässiger als for f in $(ls)wenn ein Dateiname enthält Leerzeichen oder einen glob Charakter. (Es wird jedoch fehlschlagen, wenn sich keine Dateien im CWD befinden, sodass Sie diesen Fall überprüfen müssen.)
Einmischen mit: Dateien, denen ein "-" vorangestellt ist, in beliebigen Ordnern, die unerwünschte Schalter auslösen. Das Entfernen macht erst dann viel Spaß, wenn Sie feststellen, dass rm ./-stupidfile funktioniert.
14.
1
@ ǝɲǝɲbρɯͽ Mir ist aufgefallen, dass ich den Inhalt eines Verzeichnisses mit Dateien löschen musste, deren Dateiname Positionen in einem Koordinatensystem von -1024x-1024 bis 1024x1024 darstellt. Da habe ich zum ersten Mal gelernt, wie man flüchtet.
Jarmund,
5
Wie bereits erwähnt, dehnt sich die Schale *so echoals Argumente , was auch immer die Shell finden im aktuellen Verzeichnis erhalten. Beachten Sie jedoch, dass, wenn die Erweiterung zu nichts führt, dh in diesem Fall, wenn das Verzeichnis keine nicht ausgeblendeten Dateien enthält, die *unverändert bleiben und wie an den aufgerufenen Befehl übergeben werden (es sei denn, mit einigen Shells wie 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 eine Datei mit dem Namen temp*im aktuellen Verzeichnis angelegt, wenn noch nicht mindestens eine Datei mit dem Namen beginnt temp.
Wenn Sie möchten *, dass die Übergabe in jedem Fall unverändert bleibt, können Sie sie mit einfachen Anführungszeichen '*', doppelten Anführungszeichen "*"oder umgekehrten Schrägstrichen vor der Erweiterung schützen \*.
In Bash befasst sich die Shell damit. Sie sehen das, wenn Sie es sogar *ohne Echo versuchen
Auf der Grundlage einiger Kommentare würde ich bei der Ausführung von * ENTER vorschlagen, ein Verzeichnis zu erstellen und mit dem Befehl touch einige Dateien zu erstellen. Stellen Sie sicher, 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
So ls *ist ein bisschen ein Klischee
In Windows *wird der Befehl verarbeitet, dir *.*ist also kein Klischee.
Hinweis: Ich möchte hinzufügen, dass bei einigen Kommentaren das Risiko besteht, dass * und dann die EINGABETASTE ausgeführt werden. Wenn Sie eine Datei mit dem Namen rm haben, die sich zuerst in der Verzeichnisliste befindet, ist dies gefährlich, da alle darauf folgenden Dateien gelöscht würden. Auch und dies ist weniger unwahrscheinlich, wenn die erste Datei in der Verzeichnisliste der Name eines Skripts im Pfad ist, wird dieses ausgeführt.
Beachten Sie, dass es rmnatürlich auch eine Datei mit dem Namen geben kann.
Volker Siegel
1
... und eine andere namens -rf
ǝɲǝɲbρɯͽ
1
@ ǝɲǝɲbρɯͽ Kannst du eine Datei haben, deren Dateiname ist -rf? Ich habe versucht , touch -rfund , touch \-rfaber es ist es nicht zu schaffen.
Barlop
@barlop habe ich oben kommentiert; Die GUI (wie Gedit) handhabt sie gut, aber da die Shell (zumindest Bash) dies durchläuft, benötigt sie ./ davor. Sollten Sie jemals versehentlich eine solche Datei erstellt haben, versucht rm dies anzudeuten, aber wenn nicht: Ich hoffe, dass dies immer nur in einem temporären Ordner mit Einwegkindern endet.
15.
@ ǝɲǝɲbρɯͽ Ich verstehe überhaupt nicht, was Sie meinen. Ich frage mich, wie Sie eine Datei mit dem Namen erstellen können -rf. (Ich verstehe die Gefahr einer Datei mit dem Namen rm und einer Datei mit dem Namen -rf und das Problem, * einzugeben und die Eingabetaste in einem wichtigen Ordner zu drücken, ich habe nicht vor, dies zu tun)
Technisch gesehen ist das, was Sie schreiben, korrekt, aber ohne die Links kann diese Antwort die Frage nicht wirklich beantworten. Erwägen Sie die Einbeziehung der relevanten Details.
ein CVn
@ MichaelKjörling Ich stimme der Sache mit den Links zu, aber das OP hat einfach gefragt, ob die Shell oder der Befehl selbst die Argumente handhabt. Glenns Antwort besagt lediglich, dass die Shell sie behandelt, daher ist es eine akzeptable Antwort auf die Frage.
Slhck
@slhck Aus diesem Grund habe ich nicht als NAA gemeldet: Es ist noch etwas übrig, das die Frage beantwortet, nachdem die Links entfernt wurden. Das heißt nicht, dass dies meiner Meinung nach eine gute Antwort ist. (Ich sehe jetzt, dass mein erster 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 belassen, wo er ist.)
ein Lebenslauf vom
@ MichaelKjörling Einverstanden. Ich habe gerade den Kommentar für diejenigen hinterlassen, die ihn als NAA gekennzeichnet haben (und dies tun werden).
Antworten:
bash (oder was auch immer Sie als Shell verwenden) ist das erste, was Sie lesen, und beginnt mit der Interpretation von Sonderzeichen wie
?
und*
.*
wird auf alle Übereinstimmungen in der CWD erweitert , was bedeutet, dass der Stern durch diese Übereinstimmungen ersetzt wird.In den meisten Fällen ist dies recht unübersichtlich, kann jedoch von Zeit zu Zeit zu verwirrenden Fällen führen.
Folgendes berücksichtigen. Ein Verzeichnis hat diesen Inhalt:
Wenn du dann
mv *
etwas scheinbar Seltsames eingibst, passiert:test3
ist da, aber der Rest ist weg. Obwohl es anfangs seltsam ist, macht es Sinn, wenn Sie erst einmal verstanden haben, an was die Bash tatsächlich gehtmv
. Aufgrund des Sterns interpretiert Bashmv *
alsmv test test1 test2 test3
und wenn MV diese Liste erhält, wird davon ausgegangen, dass das letzte Argument das Ziel ist, an das alle Dateien verschoben worden wären.Wie für die Befehle, die Sie aufgelistet haben:
echo *
kann als ein Armenmann funktionierenls
. Die Shell erweitert den Stern auf das, was sich in diesem Verzeichnis befindet, und gibt, wie Sie sicher bereits wissen,echo
buchstäblich alle Bashs aus, die ihr als Argumente übergeben wurden.cp temp temp*
verhält sich ähnlich wie dermv
oben beschriebene Befehl, es sei denn, es gibt nur ein Verzeichnis mit dem Namen temp. In diesem Fall sind Quell- und Zielname identisch, dh es wird nichts unternommen.quelle
*
stattls
. Zum Beispielfor f in *; do
ist mehr zuverlässiger alsfor f in $(ls)
wenn ein Dateiname enthält Leerzeichen oder einen glob Charakter. (Es wird jedoch fehlschlagen, wenn sich keine Dateien im CWD befinden, sodass Sie diesen Fall überprüfen müssen.)shopt nullglob
ist.echo *
diesem Trick können Sie in einigen Fällen sparen .Wie bereits erwähnt, dehnt sich die Schale
*
soecho
als Argumente , was auch immer die Shell finden im aktuellen Verzeichnis erhalten. Beachten Sie jedoch, dass, wenn die Erweiterung zu nichts führt, dh in diesem Fall, wenn das Verzeichnis keine nicht ausgeblendeten Dateien enthält, die*
unverändert bleiben und wie an den aufgerufenen Befehl übergeben werden (es sei denn, mit einigen Shells wie werden nicht standardmäßige Optionen verwendetbash
).echo *
wird sich dann nicht wie ein armer Mann verhalten,ls
da der erstere nichts druckt, während der letztere druckt*
.Ebenso
cp /tmp/temp temp*
wird eine Datei mit dem Namentemp*
im aktuellen Verzeichnis angelegt, wenn noch nicht mindestens eine Datei mit dem Namen beginnttemp
.Wenn Sie möchten
*
, dass die Übergabe in jedem Fall unverändert bleibt, können Sie sie mit einfachen Anführungszeichen'*'
, doppelten Anführungszeichen"*"
oder umgekehrten Schrägstrichen vor der Erweiterung schützen\*
.quelle
In Bash befasst sich die Shell damit. Sie sehen das, wenn Sie es sogar
*
ohne Echo versuchenAuf der Grundlage einiger Kommentare würde ich bei der Ausführung von * ENTER vorschlagen, ein Verzeichnis zu erstellen und mit dem Befehl touch einige Dateien zu erstellen. Stellen Sie sicher, dass keine oder zumindest die erste alphabetisch nicht der Name ist eines Skripts oder Befehls im Pfad.
So
ls *
ist ein bisschen ein KlischeeIn Windows
*
wird der Befehl verarbeitet,dir *.*
ist also kein Klischee.Hinweis: Ich möchte hinzufügen, dass bei einigen Kommentaren das Risiko besteht, dass * und dann die EINGABETASTE ausgeführt werden. Wenn Sie eine Datei mit dem Namen rm haben, die sich zuerst in der Verzeichnisliste befindet, ist dies gefährlich, da alle darauf folgenden Dateien gelöscht würden. Auch und dies ist weniger unwahrscheinlich, wenn die erste Datei in der Verzeichnisliste der Name eines Skripts im Pfad ist, wird dieses ausgeführt.
quelle
rm
natürlich auch eine Datei mit dem Namen geben kann.-rf
? Ich habe versucht ,touch -rf
und ,touch \-rf
aber es ist es nicht zu schaffen.-rf
. (Ich verstehe die Gefahr einer Datei mit dem Namen rm und einer Datei mit dem Namen -rf und das Problem, * einzugeben und die Eingabetaste in einem wichtigen Ordner zu drücken, ich habe nicht vor, dies zu tun)Die Shell führt mehrere Erweiterungen durch, bevor die Argumente an den Befehl übergeben werden.
Siehe auch https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion
Nicht bash-spezifisch, siehe http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01
quelle