Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

    
            
  •              Cómo escapar os.system () llama?                                      10 respuestas                          
  •     
    

¿Hay algo en la biblioteca estándar de Python que analizar adecuadamente / cuerdas unparse para usar en comandos shell? Busco el análogo de pitón a String::ShellQuote::shell_quote de Perl:

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

Y, aún más importante, algo que va a trabajar en la dirección inversa (tomar una cadena y se descomponen en una lista).

¿Fue útil?

Solución

pipes.quote está ahora shlex.quote en Python 3. Es bastante fácil de usar ese pedazo de código.

https://github.com/python/cpython/ blob / maestro / lib / shlex.py # L281

Esa versión maneja el argumento de longitud cero correctamente.

Otros consejos

Parece

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 molesta lo suficiente.

Estoy bastante seguro de que pipes.quote se rompe, y no debe ser utilizado, ya que no se ocupa de argumentos de longitud cero correctamente:

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

Creo que el resultado debería ser algo así como

mycommand arg1 '' arg3

Para citar cáscara, esto funciona: rigurosamente que he probado en POSIX. [Estoy asumiendo que la función list2cmdline suministrada por Python funciona como se anuncia en 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 ])

Las pruebas son aquí , si a alguien le interesa.

A fin de la cita, trate shlex.split()

Usted debe nunca tener que pagar cotización. La forma correcta de hacer una orden es no hacer la cáscara citando y en su lugar utilizar subprocess.call o subprocess.Popen , y pasar una lista de argumentos no cotizados. Este es inmune a la cabeza de expansión.

es decir.

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

Si desea Unquote cáscara citó datos, puede utilizar shlex.shlex como esto:

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

El subproceso módulo de biblioteca estándar tiene la función list2cmdline que hace esto, aunque de acuerdo con reglas de Microsoft así que no estoy seguro de cómo funciona fiable en entornos Unix para las líneas de comandos más complicados.

El quotefunction está disponible desde hace bastante tiempo (Python 2.7?) -. El mayor inconveniente es que se movió desde el módulo pipe a shlex entre 3,2 y 3,3

Usted tiene que estar preparado para manejar ambos casos, mientras que la importación de esa función:

try:
    from shlex import quote
except ImportError:
    from pipes import quote
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top