OVH Cloud OVH Cloud

questions sur les quotes

11 réponses
Avatar
David LE BOURGEOIS
Bonjour.

Plusieurs petites choses me trottent dans la tête.

1) Les backquotes :

david@abeille ~/tmp $ perl -e '`echo foo` or warn; print "$?\n";'
0
david@abeille ~/tmp $ perl -e '`echo foo > bar` or warn; print "$?\n";'
Warning: something's wrong at -e line 1.
0
david@abeille ~/tmp $ ls bar
bar

Qu'est-ce qui ne va pas ?

2) Pour afficher une simple quote je ne trouve pas mieux que :

perl -e 'print "'\''\n"'

Et vous ?

3) Comment protéger une variable lors d'un appel à system() ?

david@abeille ~/tmp $ perl -ne 'chomp;`touch '\''$_'\''`' <<FIN
heredoc> a
heredoc> b
heredoc> c
heredoc> l'exception
heredoc> FIN
sh: -c: line 1: unexpected EOF while looking for matching `''
sh: -c: line 2: syntax error: unexpected end of file
david@abeille ~/tmp $ ls a b c
a b c

Je pourrai protéger avec des ", mais le problème reste le même avec '.
De plus, les variables contenant "$(rm -rf ~)" pourraient faire mal !

J'avais penser combiner les " avec un if /^\w+$/ pour protéger, mais je
n'ai rien trouver d'autre dans perlsec.

Avez-vous des idées ?


Merci d'avance pour vos réponses.

--
David LE BOURGEOIS

10 réponses

1 2
Avatar
Benoit Izac
Bonjour,

le 28/04/2004 à 20:44, David LE BOURGEOIS a écrit
dans le message <408ffb86$0$20163$ :

Plusieurs petites choses me trottent dans la tête.

1) Les backquotes :

~/tmp $ perl -e '`echo foo` or warn; print "$?n";'
0
~/tmp $ perl -e '`echo foo > bar` or warn; print "$?n";'
Warning: something's wrong at -e line 1.
0
~/tmp $ ls bar
bar

Qu'est-ce qui ne va pas ?


« or warn »
les « `` » sont fait pour exécuter des commandes shell et en récupérer
la sortie (en contexte scalaire ou de liste). Si tu veux un contrôle
pour savoir si la commande échoue utilise open().


2) Pour afficher une simple quote je ne trouve pas mieux que :

perl -e 'print "'''n"'

Et vous ?


Tu sembles utiliser zsh :
perl -e $'print "'n"'
C'est un problème de shell, pas de Perl, regarde ton manuel.

3) Comment protéger une variable lors d'un appel à system() ?

~/tmp $ perl -ne 'chomp;`touch '''$_'''`' <<FIN
heredoc> a
heredoc> b
heredoc> c
heredoc> l'exception
heredoc> FIN
sh: -c: line 1: unexpected EOF while looking for matching `''
sh: -c: line 2: syntax error: unexpected end of file
~/tmp $ ls a b c
a b c

Je pourrai protéger avec des ", mais le problème reste le même avec '.
De plus, les variables contenant "$(rm -rf ~)" pourraient faire mal !

J'avais penser combiner les " avec un if /^w+$/ pour protéger, mais
je n'ai rien trouver d'autre dans perlsec.

Avez-vous des idées ?


perl -ne 'chomp;`touch "$_"`' <<FIN
[...]
FIN

--
Benoit Izac

Avatar
David LE BOURGEOIS
Bonjour,

le 28/04/2004 à 20:44, David LE BOURGEOIS a écrit
dans le message <408ffb86$0$20163$ :


Plusieurs petites choses me trottent dans la tête.

1) Les backquotes :

~/tmp $ perl -e '`echo foo` or warn; print "$?n";'
0
~/tmp $ perl -e '`echo foo > bar` or warn; print "$?n";'
Warning: something's wrong at -e line 1.
0
~/tmp $ ls bar
bar

Qu'est-ce qui ne va pas ?



« or warn »
les « `` » sont fait pour exécuter des commandes shell et en récupérer
la sortie (en contexte scalaire ou de liste). Si tu veux un contrôle
pour savoir si la commande échoue utilise open().



OK.


2) Pour afficher une simple quote je ne trouve pas mieux que :

perl -e 'print "'''n"'

Et vous ?



Tu sembles utiliser zsh :
perl -e $'print "'n"'
C'est un problème de shell, pas de Perl, regarde ton manuel.


Oui, effectivement ça fonctionne aussi. Mais je m'étais basé sur
http://www.tldp.org/LDP/abs/html/quoting.html :

echo "Why can't I write 's between single quotes"

echo

# The roundabout method.
echo 'Why can'''t I write '"'"'s between single quotes'
# |-------| |----------| |-----------------------|
# Three single-quoted strings, with escaped and quoted single quotes
between.

# This example courtesy of Stephane Chazelas.



3) Comment protéger une variable lors d'un appel à system() ?

~/tmp $ perl -ne 'chomp;`touch '''$_'''`' <<FIN
heredoc> a
heredoc> b
heredoc> c
heredoc> l'exception
heredoc> FIN
sh: -c: line 1: unexpected EOF while looking for matching `''
sh: -c: line 2: syntax error: unexpected end of file
~/tmp $ ls a b c
a b c

Je pourrai protéger avec des ", mais le problème reste le même avec '.
De plus, les variables contenant "$(rm -rf ~)" pourraient faire mal !

J'avais penser combiner les " avec un if /^w+$/ pour protéger, mais
je n'ai rien trouver d'autre dans perlsec.

Avez-vous des idées ?



perl -ne 'chomp;`touch "$_"`' <<FIN
[...]
FIN



C'est la solution que j'utilisais avant par défaut. Et en essayant de
remplir une variable avec un bête $(touch /tmp/test), l'exécution du
programme ma créer le fichier. Ce n'est pas très sécurisé.

~/tmp $ perl -ne 'chomp;`touch "$_"`'<<FIN
$(touch aaa)
FIN
touch: création de `': Aucun fichier ou répertoire de ce type
~/tmp $ ls aaa
aaa

Mais j'ai trouvé un peu mieux :

#!/usr/bin/perl -w
while(<>) {
chomp;
print "touch $_";
s/'/'''/g;
`touch '$_'`;
print " ($_)n";
}

Et en plus, ça gère les fichiers avec des ' et des ".



Merci pour ces informations.

--
David LE BOURGEOIS


Avatar
Benoit Izac
Bonjour,

le 29/04/2004 à 15:21, David LE BOURGEOIS a écrit
dans le message <4091015a$0$17486$ :

C'est la solution que j'utilisais avant par défaut. Et en essayant de
remplir une variable avec un bête $(touch /tmp/test), l'exécution du
programme ma créer le fichier. Ce n'est pas très sécurisé.

~/tmp $ perl -ne 'chomp;`touch "$_"`'<<FIN
$(touch aaa)
FIN
touch: création de `': Aucun fichier ou répertoire de ce type
~/tmp $ ls aaa
aaa

Mais j'ai trouvé un peu mieux :

#!/usr/bin/perl -w
while(<>) {
chomp;
print "touch $_";
s/'/'''/g;
`touch '$_'`;
print " ($_)n";
}

Et en plus, ça gère les fichiers avec des ' et des ".


Si tu veux faire un script sécurisé, n'utilise pas les « `` ».

Je ne sais pas ce que tu veux faire (modifier la date ou créer un
fichier) mais perl a des fonctions pour cette usage :

- pour créer un fichier :
perl -ne 'chomp; open(FH, ">>", $_) or warn "problem: $!";
close(FH)' <<'FIN'
[...]
FIN

Si le fichier existe déja, il ne sera pas modifié.

- pour modifier la date d'un fichier utilise utime().

--
Benoit Izac

Avatar
Paul GABORIT
À (at) Wed, 28 Apr 2004 20:44:45 +0200,
David LE BOURGEOIS écrivait (wrote):
Plusieurs petites choses me trottent dans la tête.
[... plein d'exemples qui mélangent le shell et perl...]


Le premier réflexe : « diviser pour mieux régner ».

Donc, faites des tests sur l'utilisation des quotes et autres $ dans ou hors
des chaînes dans votre shell sans utiliser Perl...

Puis faites des tests sur les appels de programmes extérieurs depuis Perl mais
dans un script (en utilisant `...`, open, system avec un ou plusieurs
arguments).

Enfin, lorsque vous maîtriserez bien les deux pris séparément, tentez de les
utiliser simultanément sur une ligne de commande.

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>

Avatar
David LE BOURGEOIS


Si tu veux faire un script sécurisé, n'utilise pas les « `` ».



Je crains de ne pas avoir le choix. A moins que ...

Je ne sais pas ce que tu veux faire (modifier la date ou créer un
fichier) mais perl a des fonctions pour cette usage :

- pour créer un fichier :
perl -ne 'chomp; open(FH, ">>", $_) or warn "problem: $!";
close(FH)' <<'FIN'
[...]
FIN

Si le fichier existe déja, il ne sera pas modifié.

- pour modifier la date d'un fichier utilise utime().



Non, le touch n'est là que pour l'exemple.
En fait, le but est de lire en entrée des lignes :

1#artiste1#titre1
2#artiste2#titre2
...

Ca, c'est fait avec :

if(my ($track, $artist, $title) = /^(d+)#([^#]+)#([^#]+)$/)

Puis d'extraire avec cdparanoia la piste du CD audio, en l'envoyant par
un tube à lame qui crée un fichier mp3 contenant l'ID-Tag.
Je pensais faire comme ça :

`cdparanoia -- '$track' | lame -h --ta '$artist' --tt '$title' -
'$artist - $title.mp3'`;

Mais si le nom de l'artiste ou le titre contient une quote,
effectivement on arrive au problème shell.
Et entourrer les variables de doubles quotes, au lieu de simples, ne me
plait pas ; car voilà une ligne d'entrée qui peut faire des dégâts :

1#$(rm -rf /)#$(sync;sync;sync)

Donc, je ne vois pas d'autre solution que d'echapper les simples quotes
dans les variables.

A moins qu'il existe un module pour perl, afin d'extraire et d'encoder
des pistes audio en mp3 ... ?


--
David LE BOURGEOIS

Avatar
Benoit Izac
Bonjour,

le 29/04/2004 à 21:53, David LE BOURGEOIS a écrit
dans le message <40915d52$0$17608$ :

A moins qu'il existe un module pour perl, afin d'extraire et d'encoder
des pistes audio en mp3 ... ?


Pourquoi ne dis-tu pas ça dès le départ ?

<http://search.cpan.org/modlist/Miscellaneous>
avec Audio::CD et Audio::MPEG tu devrais pouvoir faire ce que tu veux.
--
Benoit Izac

Avatar
FDA
Donc, je ne vois pas d'autre solution que d'echapper les simples quotes
dans les variables.


http://www.icewalkers.com/Perl/5.8.0/pod/func/quotemeta.html

Avatar
David LE BOURGEOIS
Bonjour,



Bonjour.

le 29/04/2004 à 21:53, David LE BOURGEOIS a écrit
dans le message <40915d52$0$17608$ :


A moins qu'il existe un module pour perl, afin d'extraire et d'encoder
des pistes audio en mp3 ... ?



Pourquoi ne dis-tu pas ça dès le départ ?

<http://search.cpan.org/modlist/Miscellaneous>
avec Audio::CD et Audio::MPEG tu devrais pouvoir faire ce que tu veux.


Ah bah ça, c'est une bonne nouvelle !

Je viens de les récupérer et de lire la doc.
C'est exactement ce qu'il me faut.

Merci, je retourne à mon vi tout de suite...

--
David LE BOURGEOIS


Avatar
David LE BOURGEOIS

Donc, je ne vois pas d'autre solution que d'echapper les simples
quotes dans les variables.



http://www.icewalkers.com/Perl/5.8.0/pod/func/quotemeta.html


Je ne connaissais pas cette fonction.
Je la note dans mes tablettes.

Merci.

--
David LE BOURGEOIS


Avatar
David LE BOURGEOIS

À (at) Wed, 28 Apr 2004 20:44:45 +0200,
David LE BOURGEOIS écrivait (wrote):

Plusieurs petites choses me trottent dans la tête.


[... plein d'exemples qui mélangent le shell et perl...]

Le premier réflexe : « diviser pour mieux régner ».


Un de ces jours, il faudrait que je lise en entier le discourt sur la
méthode de Descartes.
Mais pour l'instant, je suis sur "Programmation en Perl" d'OReilly :-)


Donc, faites des tests sur l'utilisation des quotes et autres $ dans ou hors
des chaînes dans votre shell sans utiliser Perl...


OK, ça c'est bon.


Puis faites des tests sur les appels de programmes extérieurs depuis Perl mais
dans un script (en utilisant `...`, open, system avec un ou plusieurs
arguments).



Ca aussi c'est bon.
Mais au lieu d'un programme externe, je vais plutôt utiliser un module,
comme me l'a conseillé Benoît.

Enfin, lorsque vous maîtriserez bien les deux pris séparément, tentez de les
utiliser simultanément sur une ligne de commande.


Je crois que c'est là que j'ai cafouillé ;-)


Merci pour ces conseils.

--
David LE BOURGEOIS


1 2