Python モジュールをシェルクォート/アンシェルクォートしますか?[重複]

StackOverflow https://stackoverflow.com/questions/967443

  •  12-09-2019
  •  | 
  •  

質問

この質問にはすでに答えがあります:

Python 標準ライブラリには、シェル コマンドで使用する文字列を適切に解析/解析解除するものはありますか?Perl に類似した Python を探しています String::ShellQuote::shell_quote:

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

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

役に立ちましたか?

解決

pipes.quoteは、今のpython 3にshlex.quoteされます。 コードのその部分を使用するように十分に簡単です。

https://github.com/python/cpython/ブロブ/マスター/ 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"'

は十分に私を取得します。

私はそれが正確に長さゼロの引数を処理しないため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

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

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

つまり

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

シェルで引用されたデータの引用を解除したい場合は、次のように使用できます。 シュレックス.シュレックス このような:

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

quotefunctionはかなりの時間(?パイソン2.7)のために利用可能である - 主要な欠点は、3.2と3.3との間pipeするshlexモジュールから移動される

あなたは、その関数のインポート中に両方のケースを処理するために準備する必要があります:

try:
    from shlex import quote
except ImportError:
    from pipes import quote
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top