Módulo de Python para shellquote/unshellquote?
quoting (8)
El subproceso del módulo de biblioteca estándar tiene la función list2cmdline que hace esto, aunque de acuerdo con las reglas de Microsoft, por lo que no estoy seguro de qué tan confiable funciona en entornos similares a Unix para líneas de comando más complicadas.
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo escapar de las llamadas os.system ()? 10 respuestas
¿Hay algo en la biblioteca estándar de Python que analice / descomprima correctamente las cadenas para usar en los comandos de shell? Estoy buscando el análogo de python a la String::ShellQuote::shell_quote
de perl String::ShellQuote::shell_quote
:
$ print String::ShellQuote::shell_quote("hello", "stack", "overflow''s", "quite", "cool")
hello stack ''overflow''/'''s'' quite cool
Y, lo que es más importante, algo que funcionará en la dirección inversa (tomar una cadena y descomponerla en una lista).
Estoy bastante seguro de que pipe.quote está roto, y no debería usarse, porque no maneja correctamente los argumentos de longitud cero:
# 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 ])
Creo que el resultado debería ser algo como
>>> from pipes import quote
>>> args = [''arg1'', '''', ''arg3'']
>>> print ''mycommand %s'' % ('' ''.join(quote(arg) for arg in args))
mycommand arg1 arg3
La función de quote
está disponible durante bastante tiempo (Python 2.7?). El principal inconveniente es que se movió del módulo de pipe
a shlex
entre 3.2 y 3.3.
Tienes que estar preparado para manejar ambos casos mientras importas esa función:
try:
from shlex import quote
except ImportError:
from pipes import quote
Para shlex.split()
, prueba shlex.split()
Para la cita de shell, esto funciona: lo he probado rigurosamente en Posix. [Supongo que la función list2cmdline
proporcionada por Python funciona como se anuncia en Windows]
mycommand arg1 '''' arg3
Las pruebas están here , si a alguien le importa.
Parece
try: # py3
from shlex import quote
except ImportError: # py2
from pipes import quote
quote("hello ''s quite cool")
>>> ''"hello /'s quite cool"''
me lleva lo suficientemente lejos.
Usted nunca debe tener que citar la cotización. La forma correcta de realizar un comando es no hacer comillas de shell y, en su lugar, utilizar subprocess.call o subprocess.Popen y pasar una lista de argumentos sin comillas. Esto es inmune a la expansión de la concha.
es decir
subprocess.Popen([''echo'', ''"'', ''$foo''], shell=False)
Si desea anular la cotización de los datos de la shell, puede usar shlex.shlex como este:
list(shlex.shlex("hello stack ''overflow''/'''s'' quite cool"))
pipes.quote
ahora es shlex.quote
en python 3. Es bastante fácil usar esa pieza de código.
https://github.com/python/cpython/blob/master/Lib/shlex.py#L281
Esa versión maneja correctamente el argumento de longitud cero.