cat fichier |truc_qui_modifie >fichierCar le système commence par vider le fichier en question. On utilise alors un fichier intermédiaire dit "de travail" et on part dans ce genre d'algo :
cat fichier |truc_qui_modifie >travail mv travail fichier rm -f travail
cat fichier |truc_qui_modifie >$HOME/tmp/travail.$$ mv $HOME/tmp/travail.$$ fichier rm -f $HOME/tmp/travail.$$
fic_travail="$HOME/tmp/travail.$$" cat fichier |truc_qui_modifie >$fic_travail mv $fic_travail fichier rm -f $fic_travail
mknod fifo p cat fichier |truc_qui_modifie >fifo & cat fifo >fichier
cat fichier |truc_qui_modifie |tee fichier 1>/dev/null
generer_une_liste_de_fichier |while read fic do ....# traitement de chaque fichier ....cat $fic |truc_qui_modifie |tee $fic 1>/dev/null done
En fait, la notion de "fichier temporaire" implique de penser au nettoyage final et la gestion des accès concurrents. Que ce soit sur un vrai disque ou un ramdisk ne change rien (pour celui qui veut programmer "propre")Citation
oudoubah
Si tu peux estimer quelle est la taille de tes
fichiers lors du traitement, tu peux créer un ramdisk et y déposer tes fichiers temporaires.
J'ai essayé aussi ce genre de manip comme l'exemple suivant:Citation
oudoubah
Concernant les tubes imbriqués, il y aurait peut
être une solution (tordue) en jouant avec les
descripteurs de fichiers, ainsi les stdout seront
bien séparés.
exec 3 >fichier_a_modifier cat fichier_a_modifier |modif 1>&3Idem => Le fichier "fichier_a_modifier" est écrasé
Déjà tenté (cf premier post) iciCitation
oudoubah
Une autre solution (moins belle) serait de créer
un certain nombre de tubes nommés, et de rediriger
chaque commande dans un tel tube
mknod fifo p cat fichier |truc_qui_modifie >fifo & cat fifo >fichierLe fichier "fichier" est écrasé...
cat test1 | cat >test1; cat test1Ne donne jamais rien... l'aléatoire de tee s'expliquerait alors par ce qu'il fait en premier : s'il commence par ouvrir le fichier en écriture, rien ne s'affiche; s'il l'ouvre d'abord en lecture, le fichier est lu, fermé, pui réouvert en écriture et tout ce passe bien... Les deux opérations doivent être lancées simultanément, étant donné que c'est le but de la commande, d'où l'aléatoire...
echo -e "\n1 toto\n\n#EOF" >test1 echo -e "\n2 titi\n\n#EOF" >test2 echo -e "\n3 tutu\n\n#EOF" >test3 echo -e "\n4 tata\n\n#EOF" >test4 echo -e "\n5 tete\n\n#EOF" >test5
ls test* | while read fichier; do echo "$(cat $fichier | sed s/t/p/g )" > $fichier;done
C'était aussi mon idée. Dès que le shell interprète une redirection il commence par eraser le fichier...Citation
Mushroom
En fait, le problème doit être que l'ouverture en
écriture efface le fichier avant qu'il soit lu.
Citation
Mushroom
Perso, je ferais comme ça :
echo "$(cat "fichier_a_modifier" |truc_qui_modifie)" > fichier_a_modifier
J'ai testé plusieurs fois, ça marche très bien... mais tu as raison ça infirme l'explication... En fait, je ne comprends rien J'ai essayé ça :Citation
Sve@r
ASTUCIEUX... mais si le shell commence par faire sa redirection il commencera quand-même par eraser le fichier...
#!/bin/sh # Initialisation du test. echo -e "\n1 toto\n\n#EOF" >test1 echo -e "\n2 titi\n\n#EOF" >test2 echo -e "\n3 tutu\n\n#EOF" >test3 echo -e "\n4 tata\n\n#EOF" >test4 echo -e "\n5 tete\n\n#EOF" >test5 ls -1 test* | while read fichier; do ( # fichier en entrée standard exec 0<$fichier cat | sed s/t/p/g > $fichier ) done cat test*
echo "$(cat "fichier_a_modifier") | truc_qui_modifie > fichier_a_modifierOn se heurte à nouveau à un vidage de la cible... c'est comme si le tuyau refusait de lâcher totalement son entrée avant d'avoir atteint la fin. Si on veut vraiment un truc manipulable, il faudra sans doute passer par une variable :
#!/bin/sh # Initialisation du test. echo -e "\n1 toto\n\n#EOF" >test1 echo -e "\n2 titi\n\n#EOF" >test2 echo -e "\n3 tutu\n\n#EOF" >test3 echo -e "\n4 tata\n\n#EOF" >test4 echo -e "\n5 tete\n\n#EOF" >test5 ls -1 test* | while read fichier; do output="$(cat $fichier)" echo "$output" | sed s/t/p/g >$fichier done cat test*
Hypothèse à retenir.Citation
Mushroom
c'est comme si le tuyau refusait de lâcher totalement son entrée avant d'avoir atteint la fin.
Finallement t'as raison. Peut-être qu'il faut effectivement arrêter de se torturer le neurone et rester sur cette approche simplissime du pb. C'est dommage que Brugmans n'ait pas été tenté d'apporter sa contribution à ce topic. Il a des idées souvent top...Citation
Mushroom
Si on veut vraiment un truc manipulable, il faudra sans doute passer
par une variable :
#!/bin/sh output="$(cat fichier_a_modifier |truc_qui_modifie)" echo "$output" >fichier_a_modifier
Remarque, c'est en RAM et c'est propre une fois le script terminé.
Tiens ? C'est vraiment marrant - Je l'ai découverte aussi mi-décembre (je connaissais déjà la fonction C mais pas la commande)...Citation
Mushroom
Hello,
Autrement, tu peux jeter un oeil sur la commande
flock pour les question de non-concurrence. Je
l'ai découverte il n'y a pas longtemps.
#!/bin/sh exec 3< $1 rm $1 cut -d':' -f 1 <&3 | tr '[a-z]' '[A-Z]' i| head -n 1> $1
Citation
[oudoubah@Tuxtop tmp]$ !cp
cp /etc/passwd ./
[oudoubah@Tuxtop tmp]$ ./toto.sh passwd
[oudoubah@Tuxtop tmp]$ cat passwd
ROOT
[oudoubah@Tuxtop tmp]$
Citation
[oudoubah@Tuxtop tmp]$ cat toto.sh
#!/bin/sh
exec 3< $1
rm $1
sleep 120
[oudoubah@Tuxtop tmp]$ ./toto.sh passwd &
[1] 2762
[oudoubah@Tuxtop tmp]$ ls -l /proc/2762/fd/
total 0
lrwx------ 1 oudoubah users 64 jan 30 19:32 0 -> /dev/pts/0
lrwx------ 1 oudoubah users 64 jan 30 19:32 1 -> /dev/pts/0
lrwx------ 1 oudoubah users 64 jan 30 19:32 2 -> /dev/pts/0
lr-x------ 1 oudoubah users 64 jan 30 19:32 255 -> /tmp/toto.sh*
lr-x------ 1 oudoubah users 64 jan 30 19:32 3 -> /tmp/passwd (deleted)
[oudoubah@Tuxtop tmp]$ cp /proc/2762/fd/3 passwd2
[oudoubah@Tuxtop tmp]$ ls
enlightenment-oudoubah/ gconfd-oudoubah/ orbit-oudoubah/ passwd2 toto.sh*
Astucieux :-)Citation
oudoubah
Il y a une solution qui passe par un descripteur
de fichier, et la suppression du fichier
#!/bin/sh
exec 3< $1
rm $1
cut -d':' -f 1 <&3 | tr '' '' i| head -n
1> $1
Un exemple :
$ !cp
cp /etc/passwd ./
$ ./toto.sh passwd
$ cat passwd
ROOT
$
On utilise ici le fait qu'un fichier n'est
supprimé que lorsque tous les processus qui
l'utilisent l'ont fermé, et qu'on peut donc y
accéder via le descripteur correspondant au
fichier du processus correspondant.