Python-Modul shellquote / unshellquote? [Duplikat]
Frage
Diese Frage bereits eine Antwort hier:
- Wie zu entkommen os.system () ruft? 10 Antworten
Gibt es etwas in der Python-Standard-Bibliothek, die für die Verwendung in Shell-Befehlen richtig analysieren / unparse Strings werden? Ich bin für den Python-Analog-Perl String::ShellQuote::shell_quote
suchen:
$ print String::ShellQuote::shell_quote("hello", "stack", "overflow's", "quite", "cool")
hello stack 'overflow'\''s' quite cool
Und, was noch wichtiger ist, etwas, das in der umgekehrten Richtung (nehmen Sie einen String und zersetzen sie in eine Liste) arbeiten.
Lösung
pipes.quote
jetzt in Python 3 shlex.quote
.
Es ist leicht genug, um das Stück Code zu verwenden.
https://github.com/python/cpython/ Blob / Master / Lib / shlex.py # L281
Diese Version Griff Länge Null Argument richtig.
Andere Tipps
Sieht aus wie
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"'
wird mir weit genug.
Ich bin mir ziemlich sicher, dass pipes.quote gebrochen ist, und sollte nicht verwendet werden, weil es nicht der Länge Null Argumente nicht korrekt verarbeiten:
>>> from pipes import quote
>>> args = ['arg1', '', 'arg3']
>>> print 'mycommand %s' % (' '.join(quote(arg) for arg in args))
mycommand arg1 arg3
Ich glaube, das Ergebnis etwas wie
sein solltemycommand arg1 '' arg3
Für Shell zitiert, das funktioniert: Ich rigoros auf Posix getestet haben. [Ich gehe davon aus, dass die list2cmdline
Funktion von Python geliefert wie beschrieben auf Windows funktioniert]
# 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 ])
Die Tests sind hier , wenn jemand sich interessiert.
Um unquote, versuchen shlex.split()
Sie sollten nie Zitat Shell haben. Der richtige Weg, um einen Befehl zu tun ist, nicht Shell zu tun zu zitieren und verwenden Sie stattdessen subprocess.call oder subprocess.Popen , und eine Liste der nicht notierten Argumente übergeben. Dies ist immun Expansion zu schälen.
d.
subprocess.Popen(['echo', '"', '$foo'], shell=False)
Wenn Sie Shell-Daten zitiert unquote möchten, können Sie a href verwenden <= "http://docs.python.org/3.0/library/shlex.html?highlight=shlex#shlex.shlex" rel = "nofollow noreferrer "> shlex.shlex wie folgt aus:
list(shlex.shlex("hello stack 'overflow'\''s' quite cool"))
Der Standard-Bibliotheksmodul subprocess hat die list2cmdline Funktion, die dies tut, wenn auch nach Microsoft Regeln so bin ich nicht sicher, wie zuverlässig funktioniert es in Unix-ähnlichen Umgebungen für kompliziertere Befehlszeilen.
Die quote
function seit geraumer Zeit verfügbar ist (Python 2.7?) -. Der größte Nachteil ist es von pipe
Modul bewegte zwischen 3,2 und 3,3 bis shlex
Sie müssen bereit sein, beide Fälle zu behandeln, während diese Funktion zu importieren:
try:
from shlex import quote
except ImportError:
from pipes import quote