وحدة بيثون إلى Shellquote / غير الهزيل؟ [مكرر
سؤال
هذا السؤال لديه بالفعل إجابة هنا:
- كيفية الهروب من المكالمات Os.System ()؟ 10 إجابات
هل هناك أي شيء في مكتبة Python Standard التي ستتحليل / سلاسل غير مشروطة للاستخدام في أوامر Shell؟ أنا أبحث عن python التناظرية إلى بيرل String::ShellQuote::shell_quote
:
$ print String::ShellQuote::shell_quote("hello", "stack", "overflow's", "quite", "cool")
hello stack 'overflow'\''s' quite cool
والأهم من ذلك، شيء سيعمل في الاتجاه المعاكس (خذ سلسلة وتحلله في قائمة).
المحلول
pipes.quote
هو الآن shlex.quote
في بيثون 3. من السهل بما فيه الكفاية لاستخدام هذه القطعة من التعليمات البرمجية.
https://github.com/python/cpython/blob/master/lib/shlex.py#l281.
هذا الإصدار يتعامل مع وسيطة طول الصفر بشكل صحيح.
نصائح أخرى
يشبه
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"'
يجعلني بعيدا بما فيه الكفاية.
أنا متأكد من أن الأنابيب. يتم كسر الأنابيب، ولا ينبغي استخدامها، لأنه لا يتعامل مع حجج الطول الصفر بشكل صحيح:
>>> from pipes import quote
>>> args = ['arg1', '', 'arg3']
>>> print 'mycommand %s' % (' '.join(quote(arg) for arg in args))
mycommand arg1 arg3
أعتقد أن النتيجة يجب أن تكون شيء مثل
mycommand arg1 '' arg3
للاضطرار قذيفة، هذا يعمل: لقد اختبرته بدقة على posix. [أفترض أن list2cmdline
الوظيفة المقدمة من Python يعمل كما هو معلن على 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 ])
الاختبارات هي هنا, ، إذا كان أي شخص يهتم.
لإلغاء تحديد، حاول shlex.split()
يجب ألا تضطر أبدا إلى القشرة. الطريقة الصحيحة للقيام بأمر غير أن لا تفعل قذيفة اقتباس واستخدامها بدلا من ذلك subprocess.call. أو subprocess.popen., ، وتمرير قائمة الحجج غير المسبقة. هذا محصن من توسيع شل.
بمعنى آخر
subprocess.Popen(['echo', '"', '$foo'], shell=False)
إذا كنت ترغب في إلغاء تغيير بيانات القذيفة، فيمكنك استخدامها shlex.shlex. مثله:
list(shlex.shlex("hello stack 'overflow'\''s' quite cool"))
تحتوي وحدة المكتبة الفرعية المكتبة المعيارية على وظيفة List2cmdline التي تفعل هذا، وإن كان وفقا ل قواعد مايكروسوفت لذلك أنا لست متأكدا من مدى موثوقية أنه يعمل في بيئات مثل UNIX لمزيد من خطوط الأوامر المعقدة.
ال quote
الوظيفة متاحة لبعض الوقت (بيثون 2.7؟) - العيب الرئيسي هو انتقلت من pipe
الوحدة إلى shlex
بين 3.2 و 3.3.
يجب أن تكون مستعدا للتعامل مع كلتا الحالتين أثناء استيراد هذه الوظيفة:
try:
from shlex import quote
except ImportError:
from pipes import quote