Ich war kürzlich überrascht, als ich so etwas tat
mv ./* ../somedirectory
und feststellte, dass Dateien wie .gitignore
nicht verschoben wurden.
Ich mache den größten Teil meiner Arbeit in zsh unter OS X, und diese Überraschung hat mich in CentOS verprügelt. Ich habe Bash unter OS X versucht und das gleiche Verhalten festgestellt: *
Stimmt nicht mit Punktdateien überein. Dies scheint mir sehr unerwünscht zu sein, aber anscheinend ist es die Bash-Standardeinstellung. (Es ist vielleicht auch die zsh-Standardeinstellung, soweit ich mich erinnere, aber ich habe sie möglicherweise vor Jahren in meiner .zshrc geändert und vergessen, dass sie jemals anders funktioniert hat.)
Wie kann ich bash so konfigurieren, dass es sich wie erwartet verhält: damit * mit allen Dateien übereinstimmt und Punktdateien nicht ignoriert werden.
Falls dies überhaupt unklar ist, erfahren Sie hier, wie Sie es reproduzieren können
cd /tmp
mkdir {t,d}est
touch test/{.,}{1,2,3,4,5,6,7}
ls -hal test
mv test/* dest
ls -hal test # notice dot files are still there
ls -hal dest # notice only some files were mv'ed
Antworten:
Bash
Wie Sie bereits bemerkt haben, stimmt Bash nicht mit einem
.
am Anfang des Namens oder einem Schrägstrich überein . Um die Übereinstimmung bezüglich des Punktes zu ändern, müssen Sie diedotglob
Option - man bash :Um es mit Bash zu aktivieren / einzustellen, verwenden Sie
shopt
zB:Für zsh können Sie auch die
dotglob
Option verwenden, müssen sie jedoch verwendensetopt
, um sie zu aktivieren, z.quelle
zsh
ist die bessere Option, Dotglob pro Glob zu aktivieren :mv test/*(D) /dest
Ich habe dies getestet und es löst das Problem:
Ausgabe:
quelle
*
ist ein Glob, der von der Shell erweitert wird. Standardmäßig enthalten Shells keine Dateien, deren Name mit einem.
(als versteckte Dateien oder Punktdateien bezeichnet) beginnt, es sei denn, der führende.
wird wörtlich eingegeben.*
oder[.]*
oder?*
oder*.*
oderdir/*
wird keine Punktdateien enthalten..*
oderdir/.*
wird.So könnten Sie tun:
jedoch einige Schalen einschließlich
bash
(aber nichtzsh
,mksh
nochfish
) haben , dass misfeature dass die Ausweitung der.*
die umfassen.
und..
spezielle Verzeichniseinträge, die Sie nicht wollen , hier (und in der Regel nie eine glob aufnehmen möchten, weshalb ich es nennen misfeature).Aus diesem Grund werden Sie feststellen, dass Menschen manchmal (in Bourne-ähnlichen Muscheln) verwenden:
Das sind drei Globs, wobei der erste mit nicht versteckten Dateien übereinstimmt, der zweite mit Dateinamen beginnt,
.
gefolgt von einem anderen Zeichen als.
und der dritte mit Dateinamen,..
gefolgt von mindestens einem Zeichen.Einige moderne Muscheln haben jedoch bessere Möglichkeiten, dies zu umgehen
zsh
Mit
zsh
können Sie das(D)
Glob-Qualifikationsmerkmal verwenden, um anzugeben, dass der Glob Punktdateien enthalten soll:zsh
Es wurde auch behoben, dass andere Fehlfunktionen der Bourne-Shell darin bestehen, dass dermv
Befehl nicht ausgeführt wird , wenn das Muster nicht übereinstimmt .Wie oben gesagt wird es auch nie gehört
.
noch..
in seiner Kleckse, sowird sicher sein. Wenn jedoch keine Datei
*
oder keine Datei übereinstimmt, wird.*
der Befehl abgebrochen. Daher ist es besser, Folgendes zu verwenden:Wie in einigen anderen Shells können Sie auch alle Globs zwingen, Dotfiles einzuschließen (z. B. wenn Sie möchten, dass Dotfiles häufiger enthalten sind):
oder:
Wenn Sie danach möchten, dass ein bestimmter Glob keine Punktdateien enthält, können Sie ihn schreiben:
Oder:
Bash
Leider
bash
gibt es keine Glob-Qualifikation. Sie müssen also die Dotfile-Aufnahme global aktivieren. Inbash
lautet die Syntax:(und
[^.]*
für Globs ohne versteckte Dateien verwenden).Mit
dotglob
,bash
nicht enthalten.
noch..
in Globs wie*
, aber immer noch für Globs wie.*
.Wenn Sie die
GLOBIGNORE
Variable auf einen nicht leeren Wert setzen, wird diedotglob
Option automatisch aktiviert und es werden.
und..
von.*
Globs ausgeschlossen, jedoch nicht vondir/.*
oder.*/file
one (!), So dass der Schutz ziemlich nutzlos ist. Sie könnten tun,GLOBIGNORE='*/.:*/..:./*:../*:*/./*:*/../*'
aber dann würde es Globs wie*/.
oder./*
oder brechen../*
.Eine bessere Lösung besteht darin, Dotfiles mit Ausnahme von und
[.]*
oderdir/[.]*
oder[.]*/file
(mitdotglob
aktiviertem) zu erweitern ..
..
Fisch
fish
Globs enthalten weder.
noch..
. Wenn es je nach Version keine Übereinstimmung gibt, funktioniert es entwederzsh
(oderbash -o failglob
) oderbash -o nullglob
.Würde funktionieren, wenn es sowohl versteckte als auch nicht versteckte Dateien gibt. Andernfalls wird YMMV und bei einigen Versionen möglicherweise aufgerufen,
mv -- /dest
wenn überhaupt keine Datei vorhanden ist.ksh93
Auch kein Glob-Qualifier
ksh93
. Sie können Punktedateien in Globs einfügen mit:Im Gegensatz zu
bash
‚sGLOBIGNORE
, die richtig und auch getan behebt das Problem ,.*
einschließlich.
und..
.yash
yash
hat einedot-glob
Option (set -o dot-glob
), aber im Gegensatz dazu enthaltenbash
die Glob-Erweiterungen (sogar von*
).
und ist..
daher ziemlich nutzlos.tcsh
Funktioniert wie in
bash
,*
dh enthält Punktdateien mit Ausnahme von.
und enthält..
jedoch.*
weiterhin.
und..
(und Sie können[.]*
versteckte Dateien mit Ausnahme von.
und erweitern..
).quelle
Der einfachste Weg in Bash, passende Punktdateien zu drucken, zu ignorieren
.
und..
ist:Zu testen:
Es wurden alle Dateien mit oder ohne Punkte gedruckt, mit Ausnahme von
.
und..
.Ihr Beispiel wird auch richtig funktionieren:
Leeren Sie wichtige Dateien.
Die Systemdateien sind
.
..
noch vorhanden, werden jedoch von einer Shell-Erweiterung (mit *) nicht berücksichtigt.Und das dest ination Verzeichnis enthält alle Dateien:
Warum?
Dies funktioniert , weil Einstellung GLOBIGNORE Dies hat Nebenwirkungen:
shopt -s dotglob
) auf mathematische Punktdateien für Erweiterungen..
und..
werden ignoriert, wenn GLOBIGNORE gesetzt und nicht null ist.Details im Handbuch :
LESS=+'/The GLOBIGNORE' man bash
.Außerdem müssen wir die Variable GLOBIGNORE so einstellen, dass sie einen Namen enthält, mit dem kein Dateiname übereinstimmen kann:
einen Schrägstrich (und etwas anderes, nur als doppelte Vorsichtsmaßnahme).
Es kann nützlich sein, auch nullglob festzulegen, wenn dies erforderlich ist, um zu vermeiden, dass eine
*
Datei angezeigt wird, wenn keine entsprechende Datei vorhanden ist*
.quelle
Sehr interessiert diese Einstellung von GLOBIGNORE = / + / @ user79743
Aus meiner Erfahrung Entschärfen ist dotglob schlechtes Geschäft für fast alle Ihre Befehle (cp, mv usw.) , aber das gleiche gilt Einstellung die nullglob (vor allem mit regulären Ausdrücken , die dann brauchen Flucht!).
Wenn Sie sie jedoch zu Beginn Ihres Programms festlegen müssen, aber in bestimmte Bereiche eingreifen müssen, in denen Sie Befehle wie cp, mv usw. aufrufen oder reguläre Ausdrücke verwenden, gehen Sie wie folgt vor:
quelle