OVH Cloud OVH Cloud

Un fifo?

15 réponses
Avatar
Kevin Denis
Bonjour,

je suis en train de regarder le redirect_program de squid.

Un exemple de ce qui marche, (en perl):

#!/usr/bin/perl
$|=1;
while(<>)
{
s@http://www.microsoft.com@http://www.kernel.org@;
print;
}

En gros, le prog attend une entree, et la transforme.

Maintenant, je voudrais ecrire la meme chose, mais en bash.

Le truc simple comme:
#!/bin/bash
URL=$1
lynx -dump -source | clamdscan - --quiet
if [ $? -eq 0 ]
then
echo $URL
else
echo http://www.virus-jackal.net/infected.php
fi

ne fonctionne pas. Je pense que c'est du au fait que le programme
doit boucler sur lui meme. Mais comment recuperer le $1? Avec un fifo
je pense, mais comment?

Merci

--
Kevin

10 réponses

1 2
Avatar
Vincent Bernat
OoO En cette nuit nuageuse du mardi 01 février 2005, vers 01:33, Kevin
Denis disait:

Le truc simple comme:
#!/bin/bash
URL=$1
lynx -dump -source | clamdscan - --quiet
if [ $? -eq 0 ]
then
echo $URL
else
echo http://www.virus-jackal.net/infected.php
fi

ne fonctionne pas. Je pense que c'est du au fait que le programme
doit boucler sur lui meme. Mais comment recuperer le $1? Avec un fifo
je pense, mais comment?


while read url; do
...
done
--
prom_printf("Detected PenguinPages, getting out of here.n");
2.0.38 /usr/src/linux/arch/sparc/mm/srmmu.c

Avatar
Stephane Chazelas
2005-01-31, 20:43(+01), Vincent Bernat:
[...]
while read url; do
...
done


L'equivalent de while (<>) serait plutot:

while IFS= read -r _; do
_="$_
"
...
done


while read url (avec la valeur par defaut d'IFS) ca serait
quelque chose comme:

while ($url = <>) {
while ($url =~ /^(?:.|[^])*$/ && ($_ = <>)) {
$url = substr($url, 0, -2) . $_;
}
$url =~ s/^s*(.*?)s*$/$1/;
$url =~ s/(.)/$1/g;
$url =~ s/^((?:.|[^])*)$/$1/;
...
}

Les seuls cas ou ca fait du sens d'appeler read sans -r et sans
changer IFS, c'est quand on veut lire plusieurs champs separés
par des blancs et permettre qu'un "" /echappe/ le separateur de
champs et permette de continuer une ligne logique sur plusieurs
lignes physique.

Exemple:

while read a b c; do

et vouloir qu'avec un input comme:

1er champ champ2 champ
3 et suivants

a recoive "1er champ", b "champ2", c "champ3 et suivants"


--
Stéphane

Avatar
cedric
Stephane Chazelas wrote:
L'equivalent de while (<>) serait plutot:

while IFS= read -r _; do
_="$_
"
...
done


Comprend pas. Read n'est-il pas censé lire une ligne complète, et
n'utiliser IFS que pour assigner les mots de la lignes aux différentes
variables (en mettant tout le reste de la ligne, s'il reste des mots,
dans la dernière variable) ?

Donc, read toto lit bien une ligne, et while read serait équivalent à
while (<>)...?

Qu'est-ce que j'ai raté ?

Avatar
Stephane Chazelas
2005-02-01, 11:08(+01), cedric:
Stephane Chazelas wrote:
L'equivalent de while (<>) serait plutot:

while IFS= read -r _; do
_="$_
"
...
done


Comprend pas. Read n'est-il pas censé lire une ligne complète, et
n'utiliser IFS que pour assigner les mots de la lignes aux différentes
variables (en mettant tout le reste de la ligne, s'il reste des mots,
dans la dernière variable) ?

Donc, read toto lit bien une ligne, et while read serait équivalent à
while (<>)...?

Qu'est-ce que j'ai raté ?


Oui, read, par defaut, fait plus que lire une ligne d'input (ca
n'a rien a voir avec while).:

$ printf '%sn' ' a b ' | bash -c 'read a; printf "<%s>n" "$a"'
<a b>
$ printf '%sn' ' a b ' | bash -c 'read -r a; printf "<%s>n" "$a"'
<a b>
$ printf '%sn' ' a b ' | bash -c 'IFS= read -r a; printf "<%s>n" "$a"'
< a b >

Il est surprenant que ce soit le comportement par defaut et
qu'il faille rajouter des options pour le supprimer, mais c'est
comme ca et il y a peu de chances que ca change.

--
Stéphane


Avatar
cedric
Stephane Chazelas wrote:
$ printf '%sn' ' a b ' | bash -c 'read a; printf "<%s>n" "$a"'
<a b>
$ printf '%sn' ' a b ' | bash -c 'read -r a; printf "<%s>n" "$a"'
<a b>
$ printf '%sn' ' a b ' | bash -c 'IFS= read -r a; printf "<%s>n" "$a"'
< a b >


Eureka !

Merci, je n'avais pas pensé au "trim" !

Avatar
Stephane Chazelas
2005-02-2, 19:16(+00), Kevin Denis:
[...]
#! /bin/bash

while read URL; do
cuturl=$(echo $URL | cut -d " " -f 1)
lynx -dump -accept_all_cookies -source $cuturl | clamdscan - --quiet
RES=$?

if [ $RES -eq 0 ]
then
echo $URL
else
echo $URL | sed s@$://virus.jackal-net.at/
fi

done
[...]


lynx -dump, ou lynx -source, faudrait savoir. Pour le dump, vaut
mieux utiliser elinks ou w3m. Pour le source, vaut mieux utiliser
curl, lftp ou wget.

#! /bin/sh -
virus_url='http://virus.jackal-net.at/infected.php'

while IFS=" " read -r url rest; do
if curl -qs -- "$url" < /dev/null | clamdscan --quiet -; then
printf '%sn' "$url $rest"
else
printf '%sn' "$virus_url $rest"
fi
done

des regles elementaires
- ne pas laisser une variable hors de ses quotes
- mettre des "-" ou "--" pour marquer la separation entre
options et arguments
- ne pas utiliser echo
- il n'y a aucune raison d'utiliser read sans -r dans ton
exemple.
- eviter de mettre des trucs variables dans un sed-script (dans
ton exemple, . et @ sont communs dans les urls et sont des
caracteres speciaux pour sed).
- [ "$?" -eq 0 ] est une noop
- faire gaffe avec l'entree standard.

auxquelles on peut rajouter:

- pourquoi utiliser bash, alors qu'on peut faire la meme chose
plus portablement
- on reserve souvent (par convention) les noms de variables en
majuscule pour les variables d'environnement.

--
Stéphane

Avatar
Kevin Denis
Le 31-01-2005, Vincent Bernat a écrit :

ne fonctionne pas. Je pense que c'est du au fait que le programme
doit boucler sur lui meme. Mais comment recuperer le $1? Avec un fifo
je pense, mais comment?


while read url; do
...
done


Ah bah oui, tout simplement. Pour ceux que ca interesse, j'ai le bout de
prog, la:

#! /bin/bash

while read URL; do
cuturl=$(echo $URL | cut -d " " -f 1)
lynx -dump -accept_all_cookies -source $cuturl | clamdscan - --quiet
RES=$?

if [ $RES -eq 0 ]
then
echo $URL
else
echo $URL | sed s@$://virus.jackal-net.at/
fi

done

comme redirect_program dans le squid.conf. Ca a l'air de marcher
(il me redirige bien quand je vais sur eicar)

Pour S.C. et l'IFS: a priori, une URL ne contiendra jamais d'espace, ca
simplifie le probleme, non?
L'URL passee au redirect_program est de la forme:
http://www.eicar.org/anti_virus_test_file.htm 192.168.1.45/zipslack - GET1
--
Kevin


Avatar
Vincent Bernat
OoO La nuit ayant déjà recouvert d'encre ce jour du mercredi 02
février 2005, vers 23:59, Kevin Denis disait:

Il y a une option pour wget? j'avais regarde, mais:
:~$ man wget | grep source
:~$


wget -O -

- pourquoi utiliser bash, alors qu'on peut faire la meme chose
plus portablement


Lequel serait le mieux? (zsh?)


A mon avis, sh suffisait pour ton programme.
--
I WILL NOT SHOW OFF
I WILL NOT SHOW OFF
I WILL NOT SHOW OFF
-+- Bart Simpson on chalkboard in episode 7F21


Avatar
Kevin Denis
Le 02-02-2005, Stephane Chazelas a écrit :

lynx -dump, ou lynx -source, faudrait savoir.


le fichier recupere a pour devenir l'analyse par clamdscan, donc j'ai bien
besoin du -source

Pour le dump, vaut
mieux utiliser elinks ou w3m. Pour le source, vaut mieux utiliser
curl, lftp ou wget.
^^^^
Il y a une option pour wget? j'avais regarde, mais:

:~$ man wget | grep source
:~$

#! /bin/sh -
virus_url='http://virus.jackal-net.at/infected.php'

while IFS=" " read -r url rest; do
if curl -qs -- "$url" < /dev/null | clamdscan --quiet -; then
printf '%sn' "$url $rest"
else
printf '%sn' "$virus_url $rest"
fi
done

Ok, j'ai mis ca en place, ca a l'air de fonctionner


des regles elementaires
- ne pas laisser une variable hors de ses quotes


meme dans le cas particulier d'une URL? (j'ai cru lire que les quotes
servent a proteger des retours chariots et espaces)

- mettre des "-" ou "--" pour marquer la separation entre
options et arguments
- ne pas utiliser echo


ah?

- il n'y a aucune raison d'utiliser read sans -r dans ton
exemple.
- eviter de mettre des trucs variables dans un sed-script (dans
ton exemple, . et @ sont communs dans les urls et sont des
caracteres speciaux pour sed).


yep, c'est vrai, pas pense a ca

- [ "$?" -eq 0 ] est une noop


noop? no operation?
:~$ ls /bin/bash
/bin/bash*
:~$ [ "$?" -eq 0 ] || echo hop
:~$ ls /bin/tagada
/usr/bin/ls: /bin/tagada: No such file or directory
:~$ [ "$?" -eq 0 ] || echo hop
hop

ca a l'air de fonctionner (??)

- faire gaffe avec l'entree standard.

comment recuperer a coup sur _toute_ l'entree standard? J'ai l'impression

que squid fait plus que donner l'URL au redirect_program, et je voudrais
dissequer un peu tout ca.

auxquelles on peut rajouter:

- pourquoi utiliser bash, alors qu'on peut faire la meme chose
plus portablement


Lequel serait le mieux? (zsh?)
J'ai ash, bash, tcsh, zsh; mais je voulais juste jouer un peu avec
ce redirect_program, je n'ai pas vraiment d'imperatif avec ce prog.

- on reserve souvent (par convention) les noms de variables en
majuscule pour les variables d'environnement.

ok.


--
Kevin

Avatar
Stephane Chazelas
2005-02-2, 22:59(+00), Kevin Denis:
[...]
mieux utiliser elinks ou w3m. Pour le source, vaut mieux utiliser
curl, lftp ou wget.
^^^^
Il y a une option pour wget? j'avais regarde, mais:

:~$ man wget | grep source
:~$


Il faut un web renderer (browser) pour transformer le source
HTML en texte ou representation audio ou graphique. wget, curl
ne sont que des logiciel de transfert de fichier, ils
n'interpretent pas le contenu des pages HTML (sauf pour
eventuellement suivre des liens dedans quand ils font un miroir
de site), donc ils ne font rien d'autre que transferer le
fichier html (donc le source).

[...]
des regles elementaires
- ne pas laisser une variable hors de ses quotes


meme dans le cas particulier d'une URL? (j'ai cru lire que les quotes
servent a proteger des retours chariots et espaces)


Non, ce n'est pas dans ce sens qu'il faut le voir. C'est plutot:

Ne pas mettre de quotes autour d'une variable permet de forcer
le decoupage en plusieurs /mots/ et de faire d'/expander/ les
/wildcards/ dedans. Donc, une variable hors de ses quotes est
une liste de patterns de fichiers (separes par les caracteres
d'IFS). Si elle ne doit pas etre vue comme telle, alors les
quotes sont necessaires.

file_list='/tmp/*.txt /tmp/*.html'
set +f; IFS=" "; cmd -- $file_list

file='/tmp/foo.txt'
cmd -- "$file"

Note que rien empeche un fichier de s'appeler '- * .txt'


- mettre des "-" ou "--" pour marquer la separation entre
options et arguments
- ne pas utiliser echo


ah?


echo est une commande non-portable et non-fiable. Meme en bash,
son comportement depend des options de compilation de bash.

Pour des valeur de var telles que:
var="-n"
var=''

Le resultat de:

echo "$var"

n'est pas garanti.

Le resultat de

printf '%sn' "$var"

l'est.

- il n'y a aucune raison d'utiliser read sans -r dans ton
exemple.
- eviter de mettre des trucs variables dans un sed-script (dans
ton exemple, . et @ sont communs dans les urls et sont des
caracteres speciaux pour sed).


yep, c'est vrai, pas pense a ca

- [ "$?" -eq 0 ] est une noop


noop? no operation?


C'est une no-op dans le sens ou elle ne sert a rien.

[ "$?" -eq 0 ] veut dire:
retourner un exit status de 0 (donc mettre $? a zero) si et
seulement si "$?" est egal a zero !

Au lieu de:

cmd
[ "$?" -eq 0 ] && echo OK

tu comprends donc que tu peux ecrire:

cmd
[ "$?" -eq 0 ]
[ ! "$?" -ne 0 ]
[ "$?" -eq 0 ]
[ ! "$?" -ne 0 ]
[ "$?" -eq 0 ] && echo OK

aussi bien que:

cmd && echo OK

- faire gaffe avec l'entree standard.

comment recuperer a coup sur _toute_ l'entree standard? J'ai l'impression

que squid fait plus que donner l'URL au redirect_program, et je voudrais
dissequer un peu tout ca.


Tu la recuperes toute. Ce que je voulais dire, c'est que comme
toutes les commandes lancees dans ce script ont leur entree
standard connectee vers cette liste d'URL, si par hasard l'une
de ces commandes veut poser une question a l'utilisateur, elle
va lire la reponse sur son entree standard, mais donc depuis la
liste de fichier, au lieu de l'utilisateur.


auxquelles on peut rajouter:

- pourquoi utiliser bash, alors qu'on peut faire la meme chose
plus portablement


Lequel serait le mieux? (zsh?)


D'utiliser une syntax POSIX qui te permettrait justement de ne
pas avoir a te poser la question de quel shell tu vas utiliser
pour interpreter le script.

- on reserve souvent (par convention) les noms de variables en
majuscule pour les variables d'environnement.

ok.



Ce n'est pas une regle d'or toutefois. Par exemple, IFS et PS1
ne sont pas par defaut dans l'environnement (et n'ont rien a y
faire)

--
Stéphane


1 2