Situation :
$ mkdir foo && touch foo/.test
$ cp foo/* .
zsh: no matches found: foo/*
(or bash : cp: cannot stat ‘foo/*’: No such file or directory)
J'ai un répertoire plein de dossiers et fichiers cachés. Que se passe-t-il et quelle est la solution?
dotglob
est traduitglobdots
par par zsh qui est un nom d'option non valide pour bash .Réponses:
Avertissement: Cette réponse traite spécifiquement de Bash, mais une grande partie s'applique à la question concernant les modèles glob!
Le caractère étoile (
*
) est un caractère générique. Il y a un certain ensemble de caractères qu'il remplacera et le premier caractère étant un point (.
) n'en fait pas partie. Ceci est un cas particulier du fait du fonctionnement des systèmes de fichiers Unix, les fichiers commençant par un point sont considérés comme "masqués". Cela signifie que les outils tels quecp
,ls
, etc. ne « voir » à moins que dit explicitement de le faire.Exemples
Créons d'abord quelques exemples de données.
Nous avons donc maintenant les éléments suivants:
Jouons maintenant à quelques jeux. Vous pouvez utiliser la commande
echo
pour lister ce que*
serait un caractère générique ( ) particulier pour une commande donnée comme ceci:Changer le comportement?
Vous pouvez utiliser la commande
shopt -s dotglob
pour modifier le comportement du*
afin que, en plus des fichiers commeregfile1
celui-ci, il corresponde également.dotfile1
.extrait du
bash
page de manuelExemple:
Vous pouvez annuler ce comportement avec cette commande:
Ta situation?
Pour vous, vous dites
cp
que vous souhaitez copier tous les fichiers qui correspondent au modèle*
, et il n'y a pas de fichiers.Ou vous pouvez le faire si vous voulez que tout soit dans le
foo
dossier:Ou vous pouvez être explicite:
Une forme plus compacte utilisant l'expansion d'accolade dans
bash
:À tout moment, vous pouvez utiliser l'
echo
astuce pour voir quels sont vos modèles de fichiers proposés (c'est le terme de fantaisie pour lequel l'étoile fait partie).Soit dit en passant, si vous allez copier un répertoire de fichiers + d'autres répertoires, vous voulez généralement le faire récursivement, c'est le
-R
passage àcp
:la source
shopt -s dotglob
,echo *
puis donne:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
ne fonctionnera généralement pas carcp
refusera de se recopierfoo
sur lui-même, vous vouliez probablement direcp -R foo/. .
. (notez quecp -R
c'est le standard).zsh
n'inclut pas.
et..
dans l'expansion de.*
. Danszsh
, si un modèle ne correspond pas, la commande est abandonnée (de manière assez sensible à nouveau), donc dans le cas général,cp foo/{,.}* .
échouera s'il n'y a pas de fichiers cachés ou non cachés.shopt
n'existe pas.Avec
zsh
, la manière typique est d'utiliser leD
qualificatif glob (pour inclure les fichiers [D] ot):Notez qu'avec ou sans
D
, les globes zsh n'incluent jamais.
ni..
(comme vous vous en doutez).la source
Le shell traite ces fichiers comme cachés lorsqu'il résout le
*
caractère, ilcp
ne reçoit donc aucun de ces noms de fichiers comme arguments.Vous pouvez les copier en spécifiant explicitement
cp foo/.* .
la source
Si ce que vous voulez faire est de copier tous les fichiers et répertoires d'un endroit à un autre, vous pouvez utiliser la
rsync
commande standard . Dans l'exemple que vous donnez ci-dessus:copiera récursivement tout le contenu de
foo
, y compris les fichiers cachés et les répertoires cachés, dans le répertoire courant. La barre oblique de fin à la fin defoo/
est importante pour rsync; avec elle, seul le contenu defoo
est copié, sans cela rsync copierafoo
également. Par exemple:-Il existe de nombreuses autres options disponibles pour modifier rsync, y compris la copie entre machines.
la source
La réponse zsh de Stéphane Chazelas est correcte pour une seule expression avec un glob. Cependant, si vous souhaitez le définir pour toutes les expressions par défaut, vous pouvez utiliser
Mettez-le dans votre
~/.zshrc
pour le rendre permanent.la source