36

シェルコマンドで使用するために文字列を適切に解析/解析解除するPython標準ライブラリに何かありますか?私はperlのPythonアナログを探していString::ShellQuote::shell_quoteます:

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

そして、さらに重要なのは、逆方向に機能するものです(文字列を取得してリストに分解します)。

4

8 に答える 8

32

のように見えます

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"'

私を十分に遠ざけます。

于 2009-07-01T18:57:34.513 に答える
10

pipes.quoteshlex.quotePython3になりました。そのコードを使用するのは簡単です。

https://github.com/python/cpython/blob/master/Lib/shlex.py#L281

そのバージョンは、長さゼロの引数を正しく処理します。

于 2014-08-05T20:19:03.983 に答える
7

pipes.quoteは壊れているので、長さゼロの引数を正しく処理しないため、使用しないでください。

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

結果は次のようなものになるはずです

mycommand arg1 '' arg3
于 2009-12-10T23:07:40.893 に答える
7

引用を解除するには、 shlex.split()

于 2011-01-26T14:14:53.120 に答える
6

シェルクォートの場合、これは機能します。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 ])

誰かが気にかけているなら、テストはここにあります。

于 2011-07-31T17:20:07.163 に答える
2

標準ライブラリモジュールサブプロセスには、これを実行するlist2cmdline関数がありますが、Microsoftの規則に従っているため、Unixライクな環境でより複雑なコマンドラインに対してどの程度信頼できるかわかりません。

于 2011-01-10T17:18:55.707 に答える
2

このquote関数はかなり長い間利用可能です(Python 2.7?)-主な欠点は、pipeモジュールからshlex3.2から3.3の間に移動したことです。

その関数をインポートする間、両方のケースを処理する準備をする必要があります。

try:
    from shlex import quote
except ImportError:
    from pipes import quote
于 2014-08-08T17:08:37.743 に答える
0

引用符をシェルする必要はありません。コマンドを実行する正しい方法は、シェルの引用符を使用せず、代わりにsubprocess.callまたはsubprocess.Popenを使用して、引用符で囲まれていない引数のリストを渡すことです。これはシェルの拡張の影響を受けません。

すなわち

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

シェルで引用されたデータの引用を解除する場合は、次のようにshlex.shlexを使用できます。

list(shlex.shlex("hello stack 'overflow'\''s' quite cool"))
于 2009-06-08T23:02:40.513 に答える