Pour développer la réponse de @Alex Gitelman :oui, il y a une différence entre "l'entrée standard" et la ligne de commande.
Lorsque vous tapez rm a.txt b.txt c.txt
, les fichiers que vous listez après rm
sont appelés arguments et sont mis à la disposition de rm via une variable spéciale (appelée argv
intérieurement). L'entrée standard, d'autre part, ressemble à un programme Unix comme un fichier nommé stdin
. Un programme peut lire les données de ce "fichier" comme il le ferait s'il ouvrait un fichier normal sur le disque et lisait à partir de celui-ci.
rm
, comme de nombreux autres programmes, prend ses arguments à partir de la ligne de commande mais ignore l'entrée standard. Vous pouvez diriger tout ce que vous voulez; il va juste jeter ces données. C'est là que xargs
est très pratique. Il lit les lignes sur l'entrée standard et les transforme en arguments de ligne de commande, ce qui vous permet de diriger efficacement les données vers la ligne de commande d'un autre programme. C'est une bonne astuce.
Par exemple :
find . -name ".txt" | xargs rm
find . -name ".txt" | grep "foo" | xargs rm
Notez que cela ne fonctionnera pas correctement s'il y a des noms de fichiers contenant des retours à la ligne ou des espaces. Pour gérer les noms de fichiers contenant des retours à la ligne ou des espaces, vous devez utiliser à la place :
find . -name ".txt" -print0 | xargs -0 rm
Cela dira find
pour terminer les résultats avec un caractère nul au lieu d'un retour à la ligne.Cependant, grep
ne fonctionnera plus comme avant. Utilisez plutôt ceci :
find . -name ".txt" | grep "foo" | tr "\n" "\0" | xargs -0 rm
Cette fois tr
est utilisé pour convertir toutes les nouvelles lignes en caractères nuls.
"pourquoi ne puis-je pas diriger le résultat vers rm ?"
Lorsque vous dirigez quelque chose vers un programme, le tube remplace l'entrée au clavier. Gardez cela à l'esprit et posez-vous la question suivante :qu'est-ce que rm
faire avec un clavier ? Supprimer vos frappes ? (un peu idiot en effet) Accepter le contrôle interactif ? (rm
n'est pas interactif sauf parfois lorsqu'il a besoin d'une confirmation, qui peut en effet être donnée par un tube.)
En effet, lorsque rm
est déjà en cours d'exécution, vous ne pouvez pas taper de commandes pour le laisser supprimer des fichiers... vous ne pouvez donc pas le faire avec un tube non plus.
Si vous gardez à l'esprit qu'un tuyau remplace la combinaison clavier/écran, les choses apparaîtront immédiatement plus logiques.
Maintenant, dans l'autre sens. Vous pouvez diriger un flux de données vers grep
.Cela signifie-t-il que vous pouvez laisser grep lire les frappes de votre clavier comme données d'entrée à la place ?
OUI! C'est en fait ce qu'il fait nativement (sans tuyauterie).
(b.t.w. notez que vous ne pouvez pas diriger ni taper l'argument de recherche dans grep
)
Alors maintenant vous savez pourquoi vous ne pouvez pas pipe vers rm et attendez-vous à ce qu'il fonctionne comme un argument de ligne de commande.
tl;dr :
Anatomie d'un programme selon la philosophie UNIX :
entrée fichier, sortie fichier, entrée clavier, sortie écran. -> Pipe ne remplace que le clavier et l'écran.
Pipe envoie la sortie de la première commande à l'entrée standard de la seconde. rm
n'accepte pas l'entrée standard, vous ne pouvez donc pas y accéder. Vous pouvez utiliser xargs
pour obtenir le même effet.Vous pouvez trouver un exemple pour xargs
spécifiquement pour votre cas dans la page de manuel pour xargs.