Question

    

Cette question a déjà une réponse ici:

    
            
  •              Comment échapper os.system () appelle                                      10 réponses                          
  •     
    

Y at-il dans la bibliothèque standard de Python qui analyser correctement les chaînes / unparse pour l'utilisation dans les commandes shell? Je cherche l'analogue python au String::ShellQuote::shell_quote de perl:

$ print String::ShellQuote::shell_quote("hello", "stack", "overflow's", "quite", "cool")
hello stack 'overflow'\''s' quite cool

Et, plus important encore, quelque chose qui va travailler dans le sens inverse (une chaîne de caractères et le décomposer en une liste).

Était-ce utile?

La solution

pipes.quote est maintenant shlex.quote en python 3. Il est assez facile d'utiliser ce morceau de code.

https://github.com/python/cpython/ blob / maître / Lib / shlex.py # L281

Cette version gère correctement l'argument zéro longueur.

Autres conseils

On dirait

try:  # py3
    from shlex import quote
except ImportError:  # py2
    from pipes import quote

quote("hello stack overflow's quite cool")
>>> '"hello stack overflow\'s quite cool"'

me reçoit assez.

Je suis assez sûr que pipes.quote est cassé, et ne doit pas être utilisé, car il ne gère pas correctement des arguments zéro longueur:

>>> from pipes import quote
>>> args = ['arg1', '', 'arg3']
>>> print 'mycommand %s' % (' '.join(quote(arg) for arg in args))
mycommand arg1  arg3

Je crois que le résultat devrait être quelque chose comme

mycommand arg1 '' arg3

Pour le shell de citer, cela fonctionne: je l'ai rigoureusement testé sur Posix. [Je suppose que la fonction list2cmdline fourni par Python fonctionne comme prévu sur Windows]

# shell.py
import os
if os.name == 'nt':
    from subprocess import list2cmdline

    def quote(arg):
        return list2cmdline([arg])[0]
else:
    import re
    _quote_pos = re.compile('(?=[^-0-9a-zA-Z_./\n])')

    def quote(arg):
        r"""
        >>> quote('\t')
        '\\\t'
        >>> quote('foo bar')
        'foo\\ bar'
        """
        # This is the logic emacs uses
        if arg:
            return _quote_pos.sub('\\\\', arg).replace('\n',"'\n'")
        else:
            return "''"

    def list2cmdline(args):
        return ' '.join([ quote(a) for a in args ])

Les tests sont , si quelqu'un se soucie.

Pour CITATION, essayez shlex.split()

Vous ne devriez jamais avoir à débourser devis. La bonne façon de faire une commande est de ne pas faire shell citer et d'utiliser plutôt subprocess.call ou subprocess.Popen , et transmettre une liste des arguments non cotées. Ceci est à l'abri de l'expansion du shell.

i.e..

subprocess.Popen(['echo', '"', '$foo'], shell=False)

Si vous voulez CITATION données cité shell, vous pouvez utiliser shlex.shlex comme ceci:

list(shlex.shlex("hello stack 'overflow'\''s' quite cool"))

Le module de bibliothèque standard de sous-processus a pour fonction de list2cmdline qui fait cela, bien que selon la règles Microsoft donc je ne sais pas comment cela fonctionne fiable dans les environnements Unix pour les lignes de commande plus complexes.

Le quotefunction est disponible depuis un certain temps (Python 2.7?) -. L'inconvénient majeur est déplacé du module il de pipe à shlex entre 3,2 et 3,3

Vous devez être prêt à gérer les deux cas, lors de l'importation de cette fonction:

try:
    from shlex import quote
except ImportError:
    from pipes import quote
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top