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 05/08/2010, à 13:41

ehmicky

[Résolu]Rediriger input et output d'une commande vers même fichier

Bonjour à tous,

Rediriger l'input et l'output d'une commande vers un même fichier, comme :

head -n -1 < FICHIER > FICHIER

voire même utiliser un fichier comme argument d'une commande, et rediriger l'output vers ce même fichier, comme :

head -n -1 FICHIER > FICHIER

a pour effet de tronquer le fichier, le rendre vide, et donc à chaque fois, je suis obligé d'utiliser un fichier intermédiaire, ou d'utiliser des commandes comme sed -i.

Mes questions seraient :
  - quelqu'un comprend-t-il pourquoi (au niveau des file descriptors) bash marche ainsi ? Je ne comprends pas pourquoi pas le fait qu'une commande Unix hérite d'un fd0 et d'un fd1 pointant vers le même fichier pose problème. hmm
  - y'a-t-il d'autres alternatives à l'utilisation d'un fichier intermédiaire ?

Merci beaucoup de votre aide sur ce petit point qui me trotte dans la tête ^^

Dernière modification par ehmicky (Le 06/08/2010, à 01:34)


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

#2 Le 05/08/2010, à 14:10

sensini

Re : [Résolu]Rediriger input et output d'une commande vers même fichier

Aucune idée du pourquoi du comment, mais tu peux toujours regarder de ce côté là http://tldp.org/LDP/abs/html/io-redirection.html#IOREDIRECTIONREF2 pour du bash only redirection style
En plus crade, tu dois pouvoir travailler avec du sed que je maîtrise pas du tout mais que je sais capable, pour stocker toutes les lignes, puis traiter les lignes une fois la lecture finie…
Sinon, regarde du côté de moreutils, sponge a l'air de répondre à tes besoins.

Et jette un coup d'œil ici aussi http://stackoverflow.com/questions/123235/problem-with-bash-output-redirection

Dernière modification par sensini (Le 05/08/2010, à 14:17)


http://doc.ubuntu-fr.org/aptitude
http://bepo.fr
Pensez à chercher sur un moteur de recherche avant de demander http://google.fr/ ;)

Hors ligne

#3 Le 05/08/2010, à 14:45

ehmicky

Re : [Résolu]Rediriger input et output d'une commande vers même fichier

Pour l'aspect technique, grâce au deuxième lien, je pense avoir compris que le problème vient du faire que si la redirection de fd1 est opéré avant celle de fd0 :
  - la redirection de fd1 tronque FICHIER
  - puis la commande Unix prend son input à partir de FICHIER, qui est cependant tronqué : l'output est alors lui-aussi tronqué.

Je regarde du côté de sponge et de <>FILE (qui semble en fait plus compliqué qu'une simple combinaison de > FILE et < FILE), en tout cas, les liens me semblent répondre complètement à ma question, je regarde de ce côté là !


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

#4 Le 05/08/2010, à 15:33

sensini

Re : [Résolu]Rediriger input et output d'une commande vers même fichier

Ah ben non, c'est clair que c'est pas du direct. En attendant, ça peut toujours être utile. (En tout cas, je connaissais pas. Maintenant si. De là à m'en servir par contre…)


http://doc.ubuntu-fr.org/aptitude
http://bepo.fr
Pensez à chercher sur un moteur de recherche avant de demander http://google.fr/ ;)

Hors ligne

#5 Le 05/08/2010, à 22:35

ehmicky

Re : [Résolu]Rediriger input et output d'une commande vers même fichier

Ok donc pour passer à côté de la création de fichiers temporaires (sale et problèmes de sécurité), et l'utilisation de commandes supplémentaires et externes (sponge, sed, ...), il y a en fait quelques solutions full-bash et simples !
A la place de :

COMMANDE <FILE >FILE

Faire :

COMMANDE <FILE 1<>FILE

Il y a aussi :

COMMANDE <<<"$(cat FILE)" >FILE

Je pense que cela marche parce que $( ) forke et donc évite le problème de redirection.
Enfin, pour avoir l'effet d'un :

COMMANDE <FILE >>FILE

On peut utiliser :

COMMANDE <>FILE >&0

L'utilisation de fd0 par <>FILE fait avancer l'offset du filedescriptor, qui dupliqué avec >&0 a le même effet que >>

Donc voilà problème résolu, et merci pour les bons liens ! ^^

Dernière modification par ehmicky (Le 05/08/2010, à 22:43)


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

#6 Le 05/08/2010, à 23:56

nesthib

Re : [Résolu]Rediriger input et output d'une commande vers même fichier

intéressant smile


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

#7 Le 06/08/2010, à 00:41

ehmicky

Re : [Résolu]Rediriger input et output d'une commande vers même fichier

Après quelques tests, il me semble que la solution avec 1<> est plus saine que <<< qui semble provoquer des messages d'erreur (et non échouer) dans des cas extrêmes (par exemple si FILE est /dev/tty)
Par contre, pour ceux que ça intéresse, y'a toujours moyen de creuser (à moins que vous sachiez !) au niveau de la question : pourquoi < FILE > FILE tronque FILE et non < FILE 1<> FILE ?
1<> FILE a pour seule différence d'autoriser la lecture de fd1 (qui peut donc être utiliser comme un "input" fd) en plus de la permission (nécessaire pour fd1) d'écriture :

$ ls -l /dev/fd/ < /dev/tty > /dev/tty
lr-x------ 1 root root 64 2010-08-06 01:33 0 -> /dev/tty
l-wx------ 1 root root 64 2010-08-06 01:33 1 -> /dev/tty
lrwx------ 1 root root 64 2010-08-06 01:33 2 -> /dev/pts/1
$ ls -l /dev/fd/ < /dev/tty 1<> /dev/tty
lr-x------ 1 root root 64 2010-08-06 01:33 0 -> /dev/tty
lrwx------ 1 root root 64 2010-08-06 01:33 1 -> /dev/tty
lrwx------ 1 root root 64 2010-08-06 01:33 2 -> /dev/pts/1

Ce qui signifierait que ce qui pose problème dans :

COMMANDE < FILE > FILE

C'est le fait que le subshell lancé par COMMANDE ait un fd1 n'ayant pas les permissions de lecture... ce qui me paraît bizarre, depuis quand les commandes Unix utilisent stdout en lecture ?? Enfin bon, l'important, c'est que ça marche au fond ^^

Autre question : pourquoi si une simple solution bash existe, 95% du code que l'on trouve sur le net utilise des solutions comme la création de fichiers temporaires ou l'utilisation d'une seconde commande ? Je pense que si c'était aussi simple, ce serait pas le cas, donc il doit bien y avoir un problème avec cette solution... sans vouloir être méfiant ^^

Dernière modification par ehmicky (Le 06/08/2010, à 00:49)


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

#8 Le 06/08/2010, à 07:06

Totor

Re : [Résolu]Rediriger input et output d'une commande vers même fichier

Bonjour,
je pense tout simplement que le fait d'utiliser le caractère ">" fait que le bash ouvre le fichier en écriture tout en le vidant. De ce fait, il est vide et la COMMANDE n'a plus de source de données.


-- Lucid Lynx --

Hors ligne

#9 Le 06/08/2010, à 07:54

credenhill

Re : [Résolu]Rediriger input et output d'une commande vers même fichier

hello

ehmicky a écrit :

Ok donc pour passer à côté de la création de fichiers temporaires (sale et problèmes de sécurité)

sed -i, ed, vim et autres éditeur utilisent des fichiers temporaires

Dernière modification par credenhill (Le 06/08/2010, à 07:55)

Hors ligne

#10 Le 06/08/2010, à 13:57

ehmicky

Re : [Résolu]Rediriger input et output d'une commande vers même fichier

Totor a écrit :

Bonjour,
je pense tout simplement que le fait d'utiliser le caractère ">" fait que le bash ouvre le fichier en écriture tout en le vidant. De ce fait, il est vide et la COMMANDE n'a plus de source de données.

Salut Totor, oui en fait ça pourrait bien résoudre la question. Du coup, < FILE prend son input à partir d'un FILE vide, et le résultat est un output vide. Ce qui voudrait dire que > FILE tronque FILE et non 1<> FILE.


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