La commande find donne cette sortie:
[root @ localhost /] # find var / log / -iname anaconda. * var / log / anaconda.log var / log / anaconda.xlog var / log / anaconda.yum.log var / log / anaconda.syslog var / log / anaconda.program.log var / log / anaconda.storage.log
Après avoir combiné avec tar, il affiche cette sortie:
[root @ localhost /] # find var / log / -iname anaconda. * -exec tar -cvf file.tar {} \; var / log / anaconda.log var / log / anaconda.xlog var / log / anaconda.yum.log var / log / anaconda.syslog var / log / anaconda.program.log var / log / anaconda.storage.log
Mais tout en listant le fichier tar, il n'affiche qu'un seul fichier
[root @ localhost /] # tar -tvf file.tar -rw ------- root / root 208454 2012-02-27 12:01 var / log / anaconda.storage.log
Qu'est-ce que je fais mal ici?
Avec xargs, j'obtiens cette sortie:
[root @ localhost /] # find var / log / -iname anaconda. * | xargs tar -cvf file1.tar
Deuxième question
Tout en tapant / devant var, signifie find /var/log
pourquoi il donne ce tar mesaage : Suppression du `/ 'en tête des noms de membres
[root @ localhost /] # find / var / log / -iname anaconda. * -exec tar -cvf file.tar {} \; tar: Suppression des `/ 'en tête des noms de membres /var/log/anaconda.log tar: Suppression des `/ 'en tête des noms de membres /var/log/anaconda.xlog tar: Suppression des `/ 'en tête des noms de membres /var/log/anaconda.yum.log tar: Suppression des `/ 'en tête des noms de membres /var/log/anaconda.syslog tar: Suppression des `/ 'en tête des noms de membres /var/log/anaconda.program.log tar: Suppression des `/ 'en tête des noms de membres /var/log/anaconda.storage.log
Sous une forme simple, quelle est la différence entre les deux suivants?
find var/log
et find /var/log
find
commande, vous devez citer le terme de recherche. Cela fonctionne sans parfois mais pas toujours.{} +
au lieu de{} \;
cela, les résultats de la recherche seront regroupés en un seul argumentRéponses:
Remarque: Voir la réponse de @ Iain pour une solution un peu plus efficace.
Notez que
find
cela appellera l'-exec
action pour chaque fichier qu'il trouve.Si vous exécutez
tar -cvf file.tar {}
pour chaquefind
sortie de fichier unique , cela signifie que vous écraserez àfile.tar
chaque fois, ce qui explique pourquoi vous vous retrouvez avec une seule archive qui ne contient queanaconda.storage.log
- ce sont les dernièresfind
sorties de fichier .Maintenant, vous voulez réellement ajouter les fichiers à l'archive au lieu de les créer à chaque fois (c'est ce que fait l'
-c
option). Alors, utilisez ce qui suit:L'
-r
option s'ajoute à l'archive au lieu de la recréer à chaque fois.Remarque: remplacez
-iname anaconda.*
par-iname "anaconda.*"
. L'astérisque est un caractère générique et peut être étendu par votre shell avantfind
même de le voir. Pour empêcher cette expansion, encapsulez l'argument entre guillemets doubles.Quant à la
tar
suppression de l'interlignage/
: l'archive ne doit contenir que des noms de fichiers relatifs . Si vous ajoutez des fichiers avec un interligne/
, ils seront stockés sous forme de noms de fichiers absolus , signifiant littéralement/var/…
sur votre ordinateur, par exemple.IIRC c'est simplement une précaution pour les
tar
implémentations autres que GNU, et c'est plus sûr de cette façon parce que vous n'écraserez pas vos données réelles/var/…
lorsque vous extrayez l'archive si elle contient des noms de fichiers relatifs.la source
tar
créer une archive de bande réelle de cette manière, en ajoutant un fichier à la fois, en rembobinant la bande, puis en relisant le tout à chaque fois pour arriver à la fin, le tout serait ridiculement lent. Votre solution ne convient que si vous écrivez le fichier tar sur le disque.find /var/log/ -iname anaconda*
ne donnant rien etfind /var/log/ -iname anaconda.*
donnant la sortie, pourquoi?find
. Donc, si vous en avezanaconda*
, et dans votre dossier actuel, il y a quelque chose nommé, par exemple,anaconda5
(correspondant à ce caractère générique), le caractère générique sera développé etfind
verra à la-iname anaconda5
place de-iname anaconda*
. Pourquoi le premier ne fonctionne pas et le second dépend des fichiers qui se trouvent dans votre répertoire actuel. @max{} +
place de{} \;
donc il regroupera les résultats de find en un seul argumentVous pouvez utiliser quelque chose comme:
Le
-print0
et-T
travailler ensemble pour autoriser les noms de fichiers avec des espaces de nouvelles lignes, etc. La finale-
indique à tar de lire les noms de fichiers d'entrée depuis stdin.Notez que cela
-print0
doit venir à la fin de votre déclaration, par cette réponse . Sinon, vous obtiendrez probablement plus de fichiers que prévu.la source
-name
option, entraînant votre solution danstar
l'ensemble du répertoire. Si c'est ce que vous voulez, vous pouvez le faire plus facilement cartar -cvf file.tar var/log
sans utiliserfind
du tout.tar
est une bonne idée. C'est certainement la meilleure solution si vous vous attendez à ce que les chemins d'accès puissent avoir des espaces. Je le décrirais même comme le meilleur techniquement, car il est à la fois fiable et efficace. Mais cela nécessite une connaissance particulière supplémentaire des deuxfind
ettar
. Je préfère la substitution de commandes à peu près uniquement parce que c'est un outil plus général: apprenez à l'utiliser une fois, puis utilisez-le partout. (Mais je concède, je suis sur Windows avec un shell où cela fonctionne toujours.) Toutes mes excuses si j'avais l'air grossier.xargs
.-print0
option find , vous avez également besoin de l'--null
option tar .--no-unquote
s'avère également nécessaire: les noms de fichiers contenant des barres obliques inverses seraient sinon mal gérés. (Non, ce n'est pas une hypothèse - je crée vraiment une archive tar à partir du code de quelqu'un d'autre, contenant un nom de fichier avec des barres obliques inversées dans le nom, c'est ainsi que j'ai découvert.)Essaye ça:
Vous essayez d'utiliser
find
pour-exec tar
. Mais la façon dont l'-exec
option fonctionne, il exécute cette commande une fois pour chaque fichier correspondant qu'il trouve, provoquant l'tar
écrasement du fichier tar qu'il produit à chaque fois. C'est pourquoi vous ne vous êtes retrouvé qu'avec le dernier. De plus, vous devez mettre des guillemets autour du motif que vous spécifiez pourfind
que le shell ne le développe pas avant de le passer àfind
.En utilisant la substitution de commandes avec des astuces (ou en utilisant la
$(...)
notation si vous préférez), la liste complète des noms produits parfind
est collée sur la ligne de commande en tant qu'argumentstar
, ce qui l'amène à les écrire tous en même temps.la source
find
est rarement une bonne idée. mywiki.wooledge.org/ParsingLsread -r
de-print0
) comme je l'ai fait dans ma réponse.question 1
Votre commande échoue car
tar
prend chacun des fichiers trouvés et les archivefile.tar
. Chaque fois qu'il le fait, il écrase le fichier créé précédemmentfile.tar
.Si vous voulez une seule archive avec tous les fichiers, exécutez simplement
tar
directement, il n'y a pas besoin defind
(et oui, cela fonctionne pour les fichiers avec des espaces dans leurs noms):question 2
Les deux commandes sont complètement différentes:
find var / log recherchera un répertoire appelé
var/log
qui est un sous-répertoire de votre répertoire actuel , il est équivalent àfind ./var/log
(remarquez le./
).trouver / var / log recherchera un répertoire appelé
/var/log
qui est un sous - répertoire de la racine,/
.Le
/
message principal vient detar
, nonfind
. Cela signifie qu'il supprime le premier/
de vos noms de fichiers pour transformer les chemins absolus en relatifs . Cela signifie que le fichier de/var/log/anaconda.error
sera extrait./var/log/anaconda.error
lorsque vous décompacterez l'archive.la source
Il y a deux façons de
-exec
travailler. Une façon exécute la commande plusieurs fois - une fois pour chaque fichier; dans l'autre sens, la commande est exécutée une fois, y compris tous les fichiers sous forme de liste de paramètres.-exec tar -cvf file.tar {} ';'
exécute latar
commande pour chaque fichier, en écrasant l'archive à chaque fois.-exec tar -cvf file.tar {} '+'
exécute latar
commande une fois, créant une archive de tous les fichiers trouvés.la source
Je pense que l'utilisation de -exec pour chaque fichier peut ralentir la compression tar, si vous avez beaucoup de fichiers. Je préfère utiliser la commande:
la source
/bin/cpio: xxx: Cannot open: Too many open files