web-dev-qa-db-fra.com

Quel est l'argument manquant pour -exec?

J'utilise la commande suivante pour effacer un répertoire, des fichiers et des répertoires de plus de 30 jours et les déplacer vers un répertoire d'archivage que je peux supprimer au bout de quelques semaines si personne ne demande la restitution de leurs fichiers. Le répertoire cible contient des sous-répertoires par nom d'utilisateur, ainsi que le répertoire d'archivage.

C'est la commande que j'utilise:

find /path/to/directory/username/ -mtime +30 -exec mv "{}" /path/to/archive/username/ \;

J'ai suggéré une version modifiée de ceci pour répondre à une question sur ask ubuntu, un autre utilisateur a modifié le code pour changer la fin de ligne \; pour + car il est plus rapide (et plus correct?). voir ici

Cependant, utiliser + de cette manière fonctionne si la commande -exec est ls -lh mais pas dans la commande réelle que j'utilise. Si je l’essaye avec + j’obtiens un message d’erreur:

find: missing argument to '-exec'

Je ne comprends pas pourquoi cela se comporte de cette façon, ni quelle serait la commande correcte. S'il vous plaît, ne postez pas simplement une correction de commande, j'aimerais comprendre plutôt que de simplement suivre une suggestion à l'aveuglette.

15
Arronical

L'utilisateur de ce message peut dire que le signe + à la fin d'une commande -exec est plus rapide, mais pas pourquoi.

Supposons que la commande find renvoie les fichiers suivants:

/path/to/file1
/path/to/file2
/path/to/file3

La commande normale -exec (-exec command {} \;) est exécutée une fois pour chaque fichier correspondant. Par exemple:

find ... -exec mv {} /target/ \;

Exécute:

mv /path/to/file1 /target/
mv /path/to/file2 /target/
mv /path/to/file3 /target/

Si vous utilisez le signe + (-exec command {} +), la commande est créée en ajoutant plusieurs fichiers correspondants à la fin de la commande. Par exemple:

find ... -exec mv -t /target/ {} +

Exécute:

mv -t /target/ /path/to/file1 /path/to/file2 /path/to/file3

Pour utiliser correctement l'indicateur +, l'argument à traiter doit figurer à la fin de la commande, pas au milieu. C'est pourquoi find trows missing argument to '-exec' dans votre exemple; il manque la fermeture {}.

19
chaos

L'utilisateur a expliqué sa modification ....

'+' exec's terminator is faster than '\;' see https://askubuntu.com/questions/558817/what-is-the-difference-between-using-and-in-exec-command; and creating a backup file from original file is good idea

... en utilisant ce lien . Je pense que fondamentalement, au lieu d’utiliser plusieurs commandes, il envoie tous les noms de fichiers à une instance de commande, pour accélérer les choses. Voici un exemple de ici :

L'utilisation de -exec avec un point-virgule (find . -exec ls '{}' \;) exécutera

ls file1
ls file2
ls file3

Mais si vous utilisez plutôt un signe plus (find . -exec ls '{}' \+), tous les noms de fichiers seront transmis en tant qu'arguments à une seule commande:

ls file1 file2 file3

Il existe d'autres formes disponibles utilisant ; et + ainsi (de ici :)

Par conséquent, la syntaxe d'exemple suivante est autorisée pour la commande find:

find . -exec echo {} \;
find . -exec echo {} ';'
find . -exec echo {} ";"
find . -exec echo {} \+
find . -exec echo {} +

CEPENDANT, je ne suis pas sûr que cela fonctionne avec la commande move, car sa syntaxe est mv [OPTION]... SOURCE DEST, sauf si l'option -t ou similaire est utilisée. Cependant, cela devrait fonctionner avec ls sans options supplémentaires, etc., car ils peuvent comprendre quand plusieurs noms de fichiers sont donnés. Le + peut également avoir besoin d'être échappé (c'est-à-dire \+)

10
Wilf