Existe-t-il une commande en ligne pour rendre chmod interactif?

24

Je cherche quelque chose comme:

ls | ask_yes_no_for_each_file | chmod +x the_files_approved

Ou une syntaxe similaire.

Peut également fonctionner sur d'autres commandes pour lesquelles vous souhaitez une confirmation individuelle.

Harvey
la source

Réponses:

45

Cela fait ce que vous cherchez:

find . -maxdepth 1 -type f -print0 | xargs -L1 -p0 chmod +x

Cela utilise findplutôt que lsparce que , généralement, l' analyse de la lssortie n'est pas fiable . Ce formulaire, en utilisant find, cependant, fonctionnera avec les noms de fichiers même s'ils contiennent des sauts de ligne ou d'autres caractères difficiles.

Explication

  • find . -maxdepth 1 -type f -print0

    Cela sélectionne les fichiers. Cela peut être personnalisé en utilisant l'une des nombreuses options de find. L'option print0indique findd'imprimer les noms de fichiers dans une liste séparée par des valeurs nulles. C'est le seul fiable à transmettre des listes de noms de fichiers.

  • xargs -L1 -p0 chmod +x

    Cela prend la liste de noms de fichiers séparés par des valeurs nulles générée par findet leur applique votre commande.

L' -L1option indique xargsde travailler sur un seul nom de fichier à la fois. L' -poption indique xargsde demander l'approbation avant de continuer. L' -0option indique xargsd'utiliser le caractère nul comme délimiteur entre les noms de fichiers.

[Je n'étais pas au courant de l' -poption jusqu'à xargsce que @kwan le fasse remarquer.]

John1024
la source
Vous pouvez rendre la findcommande POSIX compatible en utilisant -exec printf '%s\0' {} +. Ne pensez pas qu'il existe un moyen de rendre le tout compatible avec POSIX.
l0b0
Cette syntaxe me donne un avertissement find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.Ainsi , il fonctionne avec le -maxdepth 1avant -type f, comme: find . -maxdepth 1 -type f -print0 | xargs -L1 -p0 chmod +x.
Harvey
@Harvey Vous avez raison: j'ai mis à jour la réponse pour supprimer cet avertissement.
John1024
25

Vous pouvez utiliser xargs.

par exemple:

ls|xargs -I path -p chmod +x path

Option -p: Demander à l'utilisateur s'il faut exécuter chaque ligne de commande et lire une ligne à partir du terminal. Exécutez la ligne de commande uniquement si la réponse commence par «y» ou «Y».

Kwan
la source
1
+1 J'aime xargs -ptellement votre utilisation que je vais la copier.
John1024
1
Parfait! Et un moyen très simple de rendre la plupart des commandes interactives. Merci.
Harvey
@Kroltan - pourquoi quelqu'un utiliserait-il une nouvelle ligne dans un nom de fichier?
nbubis
1
@nbubis Cela peut arriver: allez dans un terminal et tapez touch "a very long file nameet appuyez sur Entrée. Voir la suite de la ligne et tapez simplement le devis de clôture et appuyez à nouveau sur Entrée. tadaa, nouvelle ligne dans le nom de fichier. Par paresse pour retaper un long nom de fichier.
Kroltan