fichier temporaire memoire ou pipe - Shell/Batch - Programmation
Marsh Posté le 17-09-2006 à 20:01:42
Il n'y a pas de "fichier en mémoire", les pipes sont, comme leur nom l'indique (trad. "tuyau" ), une redirection du flux de sortie standard vers le flux d'entrée standard.
Je ne sais pas sur quel système tu travailles mais, en plus, si tu es sous Unix, alors sache que "tout est fichier", c'est en tout cas la philosophie de l'OS.
Marsh Posté le 17-09-2006 à 20:13:53
en fait a part faire un ramdisk, je vois pas trop comment faire pour eviter que le fichier soit sur le disque dur.
le repertoite tmp sur linux est il un ramdisk d'ailleurs? ca pourrait simplifier
Marsh Posté le 17-09-2006 à 20:16:46
Mais pourquoi tu veux absolument éviter la création d'un fichier sur un disque ?
C'est pour quoi faire ?
Quant au répertoire /tmp, normalement c'est ta partition de swap. Pas vraiment un ramdisk.
Marsh Posté le 17-09-2006 à 20:24:11
le pipe c'est bien mieux. si tu peux en faire, fait le. En plus ton premier programme est fait pour. Tu as juste le deuxième a adapté. Ou bien utilise un tube nommé (man mkfifo) dans ton script. Si tu peux faire un pipe (ce qui sous entend que ton deuxième programme utilise séquentiellement les données), tu as tout a y gagner ! Fonce !
"Quant au répertoire /tmp, normalement c'est ta partition de swap. Pas vraiment un ramdisk." c'est quoi ces conneries ?
Et vos histoires de ramdisk, vous y comprenez rien. Si des fois /tmp est un tmpfs, il est vraisemblablement un point de montage distinct et n'a donc pas une capacité gigantesque. Donc a bourrer /tmp, on risque le remplir pour rien. Et si c'est un tmpfs, il verra sans doute quelque chose comme 256Meg, donc ça sera encore plus rapide. Bref, c'est une mauvaise solution, et une solution du pauvre qui en terme de performance ne pourra jamais faire plus vite que le pipe. Passe ton chemin.
Marsh Posté le 17-09-2006 à 20:27:18
Elmoricq a écrit : Mais pourquoi tu veux absolument éviter la création d'un fichier sur un disque ? |
parce que ça demande un temps considérable en écriture et en lecture et que ça demande de l'espace disque. Le simple fait que tu poses la question montre que tu ne mesure pas du tout l'ampleur du problème. Tu es donc de très mauvais conseil.
Marsh Posté le 17-09-2006 à 20:32:28
Taz a écrit : parce que ça demande un temps considérable en écriture et en lecture et que ça demande de l'espace disque. Le simple fait que tu poses la question montre que tu ne mesure pas du tout l'ampleur du problème. Tu es donc de très mauvais conseil. |
T'es sympa, mais on est dans la catégorie shell/batch, là. Les performances on s'en tape un peu, sinon on fait pas du script (enfin on ne chipotte pas sur de la lecture/écriture, quoi)
A la limite pour des questions de maintenabilité, ouais, histoire d'écrire des scripts avec pipe parce que c'est pratique, mais performances...
Et tu parles d'espaces disques, ok, mais tu les fous où tes données, dans la RAM ? T'as pas l'impression que si on est à considérer ce genre de problème, alors ce serait préférable de caser ça sur un filesystem qu'en ram, histoire de pas blinder le serveur ?
edit : et puis tu peux éventuellement prouver à quelqu'un qu'il a tort sans l'insulter, c'est pas facultatif d'être aimable. Si tu sens que c'est au-dessus de tes forces, alors va faire un footing de 2 ou 15 heures pour décompresser avant de poster
Marsh Posté le 17-09-2006 à 20:45:09
Elmoricq a écrit : T'es sympa, mais on est dans la catégorie shell/batch, là. Les performances on s'en tape un peu, sinon on fait pas du script (enfin on ne chipotte pas sur de la lecture/écriture, quoi) |
N'importe quoi. Tu dois même pas savoir ce que c'est un shell pour dire ce genre de conneries.
Elmoricq a écrit : |
C'est clair, tu ne sais pas ce qu'est un pipe.
Elmoricq a écrit : |
Ça blinde que dalle, ça ira bien moins vite que le pipe. Et au contraire, ça fragilise le fonctionnement vu qu'un tmpfs ou un /tmp sont de capacités très restreintes et peuvent donc être saturés. Et là, ça tournera plus. Un pipe a une capacité illimitée et scalera toujours de manière idéale.
Elmoricq a écrit : |
J'ai pas à prouver que t'as tort. Quand on annonce des trucs, on se renseigne un minimum sinon on dit des conneries. L'aveugle qui conseille le borgne, on s'en passe. Ton dernier message est d'un grand éclarage. Tu ne comprends pas de quoi on parle et tu n'en saisis pas la portée.
Pour en revenir au problème : adapte ton deuxième programme pour lire les données sur stdin. Genre tu boucles: tu lis un lot de donnée (une ligne peut etre), tu traite le lot de données. Ça se fait tout seul si ton programme lit les données séquentiellement.
Marsh Posté le 17-09-2006 à 23:01:45
Taz a écrit : N'importe quoi. Tu dois même pas savoir ce que c'est un shell pour dire ce genre de conneries. |
Même avec les quelques mécanismes de redirection, dans le cadre de scripts un shell c'est rien de plus qu'un interpréteur. Qui plus est, un interpréteur qui, à part les built-ins qui ne sotn pas si nombreuses, se contente d'appeler des programmes. Par définition, c'est lent.
Suffisamment en tout cas pour qu'on n'ait pas à chipoter sur d'éventuels ralentissement sur des lectures/écritures de fichier.
Taz a écrit : C'est clair, tu ne sais pas ce qu'est un pipe. |
Relis ce que j'ai marqué plus haut, j'y ai noté la définition d'un pipe.
Taz a écrit : Ça blinde que dalle, ça ira bien moins vite que le pipe. |
Nan ok mais le pipe c'est pas la solution universelle, non plus. Et avant de foncer dans le mur, ce serait bien de savoir ce que le posteur souhaite en faire, histoire de voir si c'est utilisable dans son cas, et lui expliquer.
Par exemple si "programme2" prend obligatoirement un nom de fichier en argument, et ne lit rien sur l'entrée standard, tu auras beau mettre tous les pipes que tu veux, ça ne fonctionnera pas. Après faut voir s'il a la main sur ce programme. Et même si c'est le cas, ce n'est peut-être pas forcément adaptable, en tout cas pas facilement.
Taz a écrit : Et au contraire, ça fragilise le fonctionnement vu qu'un tmpfs ou un /tmp sont de capacités très restreintes et peuvent donc être saturés. Et là, ça tournera plus. Un pipe a une capacité illimitée et scalera toujours de manière idéale. |
Je pensais surtout à un filesystem moins critique.
Marsh Posté le 17-09-2006 à 23:37:50
taz, mkfifo doit etre ce que je cherchais, je te remercie pour l'info.
en fait je pouvais pas utiliser un pipe direct dans cet exemple du moins avec les techiques d'entrée sortie que je connais
je viens de lire http://www.developpez.com/linux/guide/x1879.html qui est tres instructif sur les pipes
Marsh Posté le 18-09-2006 à 00:49:28
Elmoricq a écrit : Même avec les quelques mécanismes de redirection, dans le cadre de scripts un shell c'est rien de plus qu'un interpréteur. Qui plus est, un interpréteur qui, à part les built-ins qui ne sotn pas si nombreuses, se contente d'appeler des programmes. Par définition, c'est lent. |
mais c'est faux ! tu n'a jamais utilisé un shell ou quoi ! Tu vois bien qu'un shell lance des programmes. Un shell ça ne sert qu'à ça : les gérer, les faire communiquer. Si le shell est lent, c'est parce que lancer des tas de petits programmes ça bouffe du temps. L'interprétation du langage shell en elle même ne prend qu'une fraction ridicule du temps d'exécution. "a | b" c'est certainement pas un shell qui va ralentir ça ! Ton raisonnement est complètement faux. Tu ne sais pas de quoi tu parles. Tu ne comprends pas que le shell n'est qu'un outil et qu'une fois les processus lancés il ne sert plus à rien et ne fait plus aucune action jusqu'au lancement de la commande précédente.
Si t'as un programme qui écrit 500Mo de données. Si on est gentil a 50Mo/s en lecture et en écriture, il te faut 10s pour écrire ce fichier et à nouveau 10s pour le lire. Du gachis pur. Tu te retrouves IObound pour rien.
Exemple bidon : un process qui génère 100meg de données dont tu fais un sha1.
big | sha1sum -> ça prend 24s
big > ./out; sha1sum ./out -> on frôle les 40s.
et avec plusieurs processeurs, l'écart serait encore plus grand.
Avec les années, les programmes deviennent IOBound. C'est stupide de le faire exprès.
Elmoricq a écrit : |
là encore du n'y comprend rien. Un pipe c'est un concept. Si le concept de pipe s'applique, alors tu peux le coder. On s'en fout que le programme prenne un fichier en argument : soit tu le changes, soit tu passes à côté. T'as qu'à faire un mkfifo et on verra après si on peut pas piper ce qu'on veut ...
Elmoricq a écrit : |
pourquoi diable veut tu coller un putain de fs pour faire communiquer 2 programmes ...
Marsh Posté le 18-09-2006 à 00:53:37
attention, l'exemple de ton lien est faux.
Code :
|
ça marche fortuitement avec ls sur un petit dossier. mais avec plus de données, ls ne va pas te rendre le main. Il faut que tu lance le premier processus en arrière plan pour pouvoir lancer le deuxième. Rajoute donc un & au lancement du ls.
Marsh Posté le 18-09-2006 à 01:44:34
en fait si je pouvais utiliser le tube classique mais en utilisant "stdin".
programme1 | programme2 -c "commande STDIN"
mais voila qu'un autre probleme apparait :
je voudrais que les données sorties par le programme1 soit envoyée d'un seul bloc au programme2 et non séquetiellement, ou ligne par ligne ou autre. Ca fait planté mon programme2 si les données envoyées par programme1 sont traité trop tot j'ai l'impression.
Marsh Posté le 18-09-2006 à 10:05:12
1) si tu peux modifier ton programme2, fais le. Fais en sorte que sans argument, il lise sur stdin. Genre pas d'argument = lecture sur stdin. Sinon tant pis.
2) comment ça planté ?
Marsh Posté le 18-09-2006 à 10:38:05
en fait je peux pas modifier programme2, programme2 etant psql
y a t'il un moyen d'obliger progtamme1 a s'executer totalement avant de l'envoyer dans le pipe ?
Car ca marche en utilisant un fichier intermediaire, mais avec le pipe ca marche pas avec certains fichiers.
En fait cette sequence de script sert a importer une table paradox vers une table de postgresql et avec le pipe, psql va traiter je pense des lignes trop tot, je pense que des que psql recoit des données du pipe, il les traite pour gagner du temps, principe aussi du fifo, mais le probleme c'est qu'avec les blob de paradox, je pense que certaines lignes sont envoyées à psql en plusieurs morceaux pour la completer, enfin j'ai pas encore pu debugger, j'ai juste un message d'erreur avec "marqueur de fin de copie etc" qui m'avance pas vraiment en regardant sur google.
Marsh Posté le 18-09-2006 à 11:39:04
attend, psql c'est fastoche
echo '\dt' | psql -h host base
et ça roule tout seul.
Tu as pris en compte ma remarque à propos du mauvais exemple ?
et ce que tu penses du pipe est faux : pour psql, c'est pareil dans tous les cas, ça ne change strictement rien.
Marsh Posté le 18-09-2006 à 11:52:13
pour le mauvais exemple avec mkfifo, j'avais vu qu'il y avait un probleme en le testant mais j'ai pas étudié plus profondement.
Sinon pour psql en fait le probleme c'est que je passe par un fichier intermediaire csv. j'utilise le programe pxview qui peut transferer de paradox en csv.
et ensuite j'utilise psql -c "copy table from stdin with csv" database
et la c'est extremement rapide (j'arrive a des perfs meilleur qu'avec loaddata de mysql par exemple)
Et je suis d'accord que ca devrait marcher avec le pipe de cette facon, d'ailleurs ca marche pour 90% des tables, mais voila sur certaine table , ca marche pas.
c'est quoi BigDecimal au passage?
Marsh Posté le 18-09-2006 à 12:06:25
http://traduc.postgresqlfr.org/pgs [...] -copy.html
la y a beaucoup d'info sur le a commande copy, je vois qu'il y a ce marqueur de fin de données "\.", je verrai si c'est pas ca qui engendre mon message d'erreur.
A mon avis, c'est une histoire de protection des données. faudrait que j'utilise autre chose que CSV.
Marsh Posté le 17-09-2006 à 19:47:37
Bonjour
je voudrais eviter d'utiliser un fichier temporaire sur disque et utiliser un fichier temporaire memoire comme lors d'utilisation des pipes dans
le style de script suivant :
methode avec fichier sur disque :
programme1 > ex.out
programme2 -c "commande ex.out"
methode avec fichier en memoire ?