Situation :
$ mkdir foo && touch foo/.test
$ cp foo/* .
zsh: no matches found: foo/*
(or bash : cp: cannot stat ‘foo/*’: No such file or directory)
Ich habe ein Verzeichnis voller versteckter Ordner und Dateien. Was passiert und was ist die Lösung?
dotglob
wirdglobdots
von zsh übersetzt, was ein ungültiger Optionsname für bash ist .Antworten:
Haftungsausschluss: Diese Antwort befasst sich speziell mit Bash, aber ein Großteil davon bezieht sich auf die Frage nach Glob-Mustern!
Das Sternchen (
*
) ist ein Platzhalter. Es gibt eine Reihe von Zeichen, die an die Stelle von treten, und das erste Zeichen, das ein Punkt (.
) ist, gehört nicht dazu. Dies ist nur aufgrund der Funktionsweise der Unix-Dateisysteme ein Sonderfall. Dateien, die mit einem Punkt beginnen, gelten als "versteckt". Das bedeutet , dass Werkzeuge wiecp
,ls
etc. werden nicht „sehen“ , sofern nicht ausdrücklich so zu tun , erzählt.Beispiele
Lassen Sie uns zunächst einige Beispieldaten erstellen.
Nun haben wir also folgendes:
Lass uns jetzt ein paar Spiele spielen. Mit dem Befehl können Sie
echo
herausfinden, wie ein bestimmtes Platzhalterzeichen (*
) für einen bestimmten Befehl aussehen würde:Verhalten ändern?
Sie können den Befehl verwenden
shopt -s dotglob
, um das Verhalten der zu ändern,*
so dass neben Dateien wieregfile1
es auch übereinstimmt.dotfile1
.Auszug aus der
bash
ManpageBeispiel:
Sie können dieses Verhalten mit diesem Befehl rückgängig machen:
Deine Situation?
Für Sie sagen Sie,
cp
dass Sie alle Dateien kopieren möchten, die dem Muster entsprechen*
, und dass keine Dateien vorhanden sind.Oder Sie können dies tun, wenn Sie alles im
foo
Ordner haben möchten :Oder Sie können explizit sein:
Eine kompaktere Form mit Klammererweiterung in
bash
:Sie können den
echo
Trick jederzeit verwenden, um die von Ihnen vorgeschlagenen Dateimuster zu ermitteln (dies ist der ausgefallene Begriff für das, woraus der Stern besteht).Übrigens, wenn Sie ein Verzeichnis mit Dateien und anderen Verzeichnissen kopieren, möchten Sie dies normalerweise rekursiv tun. Das ist der
-R
Wechsel zucp
:quelle
shopt -s dotglob
,echo *
dann gibt:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
wird in der Regel nicht funktionieren, dacp
sich weigern,foo
über sich selbst zu kopieren , meinten Sie wahrscheinlichcp -R foo/. .
. (Beachten Sie, dass diescp -R
der Standard ist).zsh
nicht.
und..
in der Erweiterung von.*
. Inzsh
, wenn ein Muster nicht übereinstimmt, wird der Befehl abgebrochen wird (ganz vernünftig wieder), so im allgemeinen Fall,cp foo/{,.}* .
wird scheitern , wenn es keine versteckten ist oder keine nicht-versteckten Dateien.shopt
nicht existiert.Mit
zsh
wirdD
normalerweise das Glob-Qualifikationsmerkmal verwendet (um [D] ot-Dateien einzuschließen):Beachten Sie, dass
D
zsh-Globs.
weder mit noch ohne enthalten..
(wie zu erwarten).quelle
Die Shell behandelt diese Dateien als versteckt, wenn sie das
*
Zeichen auflöst. Siecp
erhält daher keinen dieser Dateinamen als Argumente.Sie können sie durch explizite Angabe kopieren
cp foo/.* .
quelle
Wenn Sie alle Dateien und Verzeichnisse von einem Ort an einen anderen kopieren möchten, können Sie den Standardbefehl verwenden
rsync
. Im obigen Beispiel geben Sie Folgendes an:kopiert rekursiv den gesamten Inhalt von
foo
, einschließlich versteckter Dateien und Verzeichnisse, in das aktuelle Verzeichnis. Der abschließende Schrägstrich am Ende vonfoo/
ist für rsync wichtig. damit werden nur die inhalte vonfoo
kopiert, ohne dass es rsync kopiertfoo
. Beispielsweise:-Es gibt viele andere Optionen zur Optimierung von Rsync, einschließlich des Kopierens zwischen Computern.
quelle
Die zsh- Antwort von Stéphane Chazelas ist für einen einzelnen Ausdruck mit einem Globus richtig. Wenn Sie es jedoch standardmäßig für alle Ausdrücke festlegen möchten, können Sie verwenden
Legen Sie es in Ihr
~/.zshrc
, um es dauerhaft zu machen.quelle