backslash :: protection chaine pour commande externe

Le
Eric Deveaud
Bonjour,

je sèche sur un problème que je pensait simple.

comment traiter des chaines de caratères pour protéger certains
caractéres avant de les passer au shell

j'utilise Popen avec shell=True (et j'ai besoin de shell=True)
pour récupérer des résultats de comandes externes

il se trouve qu'un cas d'utilisation me pose soucis.
les noms de fichiers à passer à mes commande comportent des
caractères qu'il me faut protéger (espace, parenthèses,
accolades et autre caractères particuliers pour le shell)

naïvement j'ai fait une boucle pour remplacer tout caractère non
alphanumérique par backslash suivi de ce caractère.

def protect_file(mmfile):
new = []
char_accepted = string.ascii_letters + string.digits +
os.path.sep
escape = '\'
for c in mmfile:
if c in char_accepted:
new.append(c)
else:
new.append(escape + c)
return ''.join(new)

le hic, c'est que du coup j'introduit 2 backslah dans ma chaine,
celle ci etant passée telle qu'elle au shell. bien évidement
l'effet n'est pas du tout celui voulu ;-(

une idée de comment m'en sortir ?

Eric
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Alain Ketterlin
Le #20572571
Eric Deveaud
comment traiter des chaines de caratères pour protéger certains
caractéres avant de les passer au shell

j'utilise Popen avec shell=True (et j'ai besoin de shell=True)
pour récupérer des résultats de comandes externes



Ca aiderait de savoir quel est le shell en question. Je suppose que
c'est un shell POSIX.

Si tu entoures ta chaîne de quotes simples (d'apostrophes), il ne te
reste plus qu'à protéger les... quotes simples. Quelque chose com me :

def p(s):
return '''"'"'''.join(["'"+t+"'" for t in s.split("'")])

(pas testé).

-- Alain.
Alain BARTHE
Le #20572661
Eric Deveaud a écrit :
Bonjour,

je sèche sur un problème que je pensait simple.

comment traiter des chaines de caratères pour protéger certains
caractéres avant de les passer au shell

j'utilise Popen avec shell=True (et j'ai besoin de shell=True)
pour récupérer des résultats de comandes externes

il se trouve qu'un cas d'utilisation me pose soucis.
les noms de fichiers à passer à mes commande comportent des
caractères qu'il me faut protéger (espace, parenthèses,
accolades et autre caractères particuliers pour le shell)

naïvement j'ai fait une boucle pour remplacer tout caractère non
alphanumérique par backslash suivi de ce caractère.

def protect_file(mmfile):
new = []
char_accepted = string.ascii_letters + string.digits +
os.path.sep
escape = '\'
for c in mmfile:
if c in char_accepted:
new.append(c)
else:
new.append(escape + c)
return ''.join(new)

le hic, c'est que du coup j'introduit 2 backslah dans ma chaine,
celle ci etant passée telle qu'elle au shell. bien évidement
l'effet n'est pas du tout celui voulu ;-(

une idée de comment m'en sortir ?

Eric



A tout hasard :

escape = ''
Alain BARTHE
Le #20572791
Alain BARTHE a écrit :
Eric Deveaud a écrit :
Bonjour,

je sèche sur un problème que je pensait simple.

comment traiter des chaines de caratères pour protéger certains
caractéres avant de les passer au shell
j'utilise Popen avec shell=True (et j'ai besoin de shell=True)
pour récupérer des résultats de comandes externes

il se trouve qu'un cas d'utilisation me pose soucis.
les noms de fichiers à passer à mes commande comportent des
caractères qu'il me faut protéger (espace, parenthèses,
accolades et autre caractères particuliers pour le shell)

naïvement j'ai fait une boucle pour remplacer tout caractère non
alphanumérique par backslash suivi de ce caractère.

def protect_file(mmfile):
new = []
char_accepted = string.ascii_letters + string.digits +
os.path.sep
escape = '\'
for c in mmfile:
if c in char_accepted:
new.append(c)
else:
new.append(escape + c)
return ''.join(new)

le hic, c'est que du coup j'introduit 2 backslah dans ma chaine,
celle ci etant passée telle qu'elle au shell. bien évidement
l'effet n'est pas du tout celui voulu ;-(

une idée de comment m'en sortir ?

Eric



A tout hasard :

escape = ''



J'ai testé :


from subprocess import Popen

p = Popen ("ls -l mon fichier", shell = True)

Ca fonctionne : il suffit donc bien d'insérer *un* devant tes
caractères spéciaux.
Alain BARTHE
Le #20572781
Eric Deveaud a écrit :
Alain BARTHE wrote:
Eric Deveaud a écrit :

escape = ''



le hasard ne nous réussi pas

Python 2.6.1 (r261:67515, Jul 7 2009, 23:51:51)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more
information.
escape = ''






File "<stdin>", line 1
escape = ''
^
SyntaxError: EOL while scanning string literal





Désolé, j'avais pas vu le problème...
Alain BARTHE
Le #20572851
Eric Deveaud a écrit :
Alain BARTHE wrote:
Eric Deveaud a écrit :

escape = ''



le hasard ne nous réussi pas

Python 2.6.1 (r261:67515, Jul 7 2009, 23:51:51)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more
information.
escape = ''






File "<stdin>", line 1
escape = ''
^
SyntaxError: EOL while scanning string literal





J'ai testé aussi :

commande = "ls -l mon" + '\' + " fichier"

print commande

p = Popen (commande, shell = True)

ca fonctionne et affiche :

ls -l mon fichier
-rw-r--r-- 1 barthe barthe 0 nov 17 16:59 mon fichier

le \ est interprété comme un seul caractère dans le print ainsi que
dans le Popen et la commande fonctionne.

J'ai pas testé avec les autres caractères spéciaux, mais ca devrait
fonctionner de même.

Sur quelle commande as tu testé ta première version ?
Alain Ketterlin
Le #20572901
Alain BARTHE
p = Popen ("ls -l mon fichier", shell = True)

Ca fonctionne : il suffit donc bien d'insérer *un* devant tes
caractères spéciaux.



Attention : le backslash disparait seulement si il précède un car actère
spécial *pour Python*, dans les autres cas il reste en place (ce qui se
passe dans l'exemple ci-dessus). Voir
http://docs.python.org/reference/lexical_analysis.html#literals
Par exemple "un deux" et "un\ deux" ont la même valeur.

-- Alain.
Eric Deveaud
Le #20572771
Alain BARTHE wrote:
Eric Deveaud a écrit :

escape = ''



le hasard ne nous réussi pas

Python 2.6.1 (r261:67515, Jul 7 2009, 23:51:51)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more
information.
escape = ''






File "<stdin>", line 1
escape = ''
^
SyntaxError: EOL while scanning string literal







Eric Deveaud
Le #20572841
Alain Ketterlin wrote:
Eric Deveaud
> comment traiter des chaines de caratères pour protéger certains
> caractéres avant de les passer au shell
>
> j'utilise Popen avec shell=True (et j'ai besoin de shell=True)
> pour récupérer des résultats de comandes externes

Ca aiderait de savoir quel est le shell en question. Je suppose que
c'est un shell POSIX.



POSIX en effet, le shell en question est sh

Si tu entoures ta chaîne de quotes simples (d'apostrophes), il ne te
reste plus qu'à protéger les... quotes simples. Quelque chose comme :

def p(s):
return '''"'"'''.join(["'"+t+"'" for t in s.split("'")])



les quotes bloquent bien l'expension de caratères "spéciaux" en
effet, j'avoue être resté bloqué sur le backslah.

c'est une solution que je vais tester ça de ce pas.

Eric
Eric Deveaud
Le #20572831
Alain BARTHE wrote:

from subprocess import Popen

p = Popen ("ls -l mon fichier", shell = True)

Ca fonctionne : il suffit donc bien d'insérer *un* devant tes
caractères spéciaux.



là est le truc comment insérer *un et un seul* backslah devant
certains caratères ?

Eric
Philippe Bouige
Le #20578101
Le 17-11-2009, Eric Deveaud
Bonjour,

je sèche sur un problème que je pensait simple.



J'ai trouvé cette solution, mais je n'ai pas mieux :-)

>>> from subprocess import Popen
>>>
>>> escape = " "[0]
>>>
>>> Popen( "ls -la", shell=True)

-rw-r--r-- 1 pbouige pbouige 0 Nov 18 11:01 (
-rw-r--r-- 1 pbouige pbouige 0 Nov 18 11:09 ( \
-rw-r--r-- 1 pbouige pbouige 0 Nov 18 11:00 ()

>>> comd1 = escape + '(' + escape + ' ' + escape

>>> Popen(comd1, shell=True)
>>> -rw-r--r-- 1 pbouige pbouige 0 Nov 18 11:01 (


>>> comd2 = 'ls -la ' + escape + '(' + escape + ' ' + escape + escape +
escape
>>> Popen(comd2, shell=True)
>>> -rw-r--r-- 1 pbouige pbouige 0 Nov 18 11:09 ( \

autre exemple :

touch '( &'
-rw-r--r-- 1 pbouige pbouige 0 Nov 18 11:22 ( &

sous python :

>>> from subprocess import Popen
>>>
>>> escape = ' '[0]
>>>
>>> cmd3 = 'ls -la ' + escape + '(' + escape + ' ' + escape + '&'
>>> Popen(cmd3, shell=True)
>>> -rw-r--r-- 1 pbouige pbouige 0 Nov 18 11:22 ( &
Publicité
Poster une réponse
Anonyme