Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 14/09/2010, à 19:58

jymere

xargs

Bonsoir.

Les premiers résultats de google concernant le rôle de la commande xargs sont troubles:

xargs est une commande UNIX puissance qui permet de récupérer les arguments passés par la commande précédante. Il permet d'éviter des structures lourdes comme :

[commande] | while read param
do
[traitement]
done
A la place, nous avons quelque chose de plus simple, de plus condensé :

[commande] | xargs [traitement]

ils donnent dans un contexte vraiment général, je n'arrive pas à saisir quand est-ce que l'on peut l'utiliser.

Wiki dit qu'il sert à remplacer un grand nombre d'arguments ceci ne m'aide pas plus.

Par contre, ils donnent des exemples et on voit que xargs s'exécute un peu comme dans une pipe et avec pas mal de commande (cp, mv, ls ...)

A quoi sert-elle précisément ?

merci

@+


Il est malpoli d'etre aigri

debian 7.5 - 64 bits - gnome

Hors ligne

#2 Le 14/09/2010, à 22:02

ehmicky

Re : xargs

Pour comprendre ce qui suit, il faut que tu saisisses la question des pipes, redirection de l'input, etc. Donc :
Fonctionnement de xargs :
  - xargs doit être suivie d'une commande (et de ses éventuelles arguments). L'action de xargs est de prendre tout ce qui lui vient en entrée standard, et de le rajouter comme des arguments supplémentaire à la commande qui le suit.
    Par exemple :

echo "/etc" "/bin" | xargs ls

est "transformé" en quelque sorte en :

ls "/etc" "/bin"

Il y a quatre utilités à xargs :
  1) La plupart des commandes prenne comme argument l'entrée standard lorsqu'elles n'ont pas d'arguments. Par exemple :

ls -A1 | wc -l

Cependant, certaines commandes ne peuvent jamais prendre l'entrée standard comme argument. Utiliser xargs est donc un truchement pour simuler ce qui leur est sinon impossible. Par exemple, dans l'exemple précédent, cela permet de piper ls, qui sinon ne peut pas être pipé.
  2) L'option -0 de xargs permet de ne pas séparer les séquences qui lui sont passée en fonction des newlines mais en fonction du caractère null (0x00). Cela est utile si le flux d'octets qui arrive dans xargs utilise null comme délimiteur, et non newline, ce qui peut arriver avec plusieurs options qui le permettent, comme find -print0. L'utilité pour find -print0 d'utiliser des null comme délimiteur, c'est que cela permet d'éviter de foutre en l'air un flux d'octets susceptible de contenir des newlines que l'on veut conserver comme telles, en utilisant null, et non newline, comme délimiteur entre chaque séquence d'input. Bon ok, je crois que j'explique assez mal, c'est plus simple que ça paraît.
  3) xargs envoie d'un coup tous les octets qu'il reçoit et balance ça pêle-mêle à la commande qui le suit. Si jamais cependant cela conduit la commande a devoir traiter 10000 arguments, Bash va crasher (xargs peut être dangereux alors). Cependant, il est impossible avec les options -I, -L et -n de xargs de définir plus finement cela. Par exemple de ne lancer qu'une invocation de la commande qui le suit pour un argument balancé. Cela peut être utile dans certains cas précis. En plus, l'option -I te permet de faire référence à l'input avec une séquence de caractère spéciaux, ce qui te permet de décupler les arguments. Exemple :

echo "/bin" | xargs -I{} echo {} {} {}

imprime "/bin /bin /bin"
  4) L'option -p ou le fait de balancer tous les inputs d'un coup peut améliorer les performances (mais bon si tu veux absolument des performances, utilise un langage compilé...)

En général, les gens l'utilisent pour le but 1) ou 2). 2) est son but initial, car il vient dans le package GNU-findutils, et a été créé pour être couplé avec find.

Edit : pour ton post initial, je pense que ce que le mec a voulu dire, c'est qu'il y a souvent plusieurs manière de rediriger la sortie d'un find :

find | COMMANDES
find -print0 | xargs -0 COMMANDES
for VAR in $(find) ; do COMMANDES ; done
find | while read VAR ; do COMMANDES ; done

Les solutions 1, 3 et 4 vont couper un nom de fichier contenant un newline en deux. Seule la solution 2 évite cela. Par ailleurs, la solution 4 peut réserver des surprises, car puisque le pipe ouvre un subshell, la boucle while utilisera des variables locales, qui ne seront plus disponibles une fois la boucle finie.
Le raisonnement marche, en dehors de find, pour tout autre commande qui produit un output composés de plusieurs lignes, et sur lequel on veut appliquer un même ensemble de commandes sur chacune des lignes produites, isolément.

Dernière modification par ehmicky (Le 14/09/2010, à 22:16)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#3 Le 15/09/2010, à 10:42

nesthib

Re : xargs

pour ta dernière remarque, concernant la portée de ta variable, la construction suivante évite le problème (si l'on considère que c'en est un)

while read line
do
    COMMANDES
done < <(COMMANDE D'ENTRÉE)

# pour un fichier en entrée
# done <fichier

# pour du texte en entrée
# done <<<'texte'

GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#4 Le 15/09/2010, à 19:18

jymere

Re : xargs

merci bien

je vais essayer de digérer tout cela

@+


Il est malpoli d'etre aigri

debian 7.5 - 64 bits - gnome

Hors ligne

#5 Le 15/09/2010, à 19:35

ehmicky

Re : xargs

jymere a écrit :

merci bien

je vais essayer de digérer tout cela

@+

Désolé, mais je crois qu'en l'occurence xargs est l'une des commandes Unix standards les plus longues à apprendre, (avec sed ou awk aussi)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne