python + subprocess.callとsedを使用してファイルの数を置き換える

python + subprocess.callとsedを使用してファイルの数を置き換える

LinuxシステムにPythonバージョンがあります - 2.7.5 - redhat 7.3

sedを使用してファイルの文字列を置き換える簡単なスクリプトを作成しました。

more  test.py
#!/usr/bin/env python


import subprocess
subprocess.call("sed s'/2.6/2.6.4/g' /tmp/file.xml")

しかし、我々は得た

Traceback (most recent call last):
  File "./test.py", line 5, in <module>
    subprocess.call("sed s'/2.6/2.6.4/g' /tmp/file.xml")
  File "/usr/lib64/python2.7/subprocess.py", line 524, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

Pythonスクリプトにどのような問題がありますか?

 more file.xml

 2.6.0.3-8

答え1

Pythonでは:

使用するとき

argsこれはすべての呼び出しに必要であり、プログラムパラメータの文字列またはシーケンスでなければなりません。一般に、さまざまなパラメータを提供することが推奨されます。これは、モジュールが必須パラメータのエスケープと引用符(ファイル名にスペースを含める)を処理できるようにするためです。これは、単一の文字列が渡される場合はshelltrueでなければなりませんTrue(以下を参照)。そうでない場合、文字列は引数を指定せずに実行するプログラムの名前のみを指定する必要があります。
...
その場合、指定されたコマンドはshellシェルTrueを介して実行されます。 Pythonがほとんどのシステムシェルによって提供される制御フローを改善するために主にPythonを使用しており、まだシェルパイプ、ファイル名ワイルドカード、環境変数拡張、ユーザー ~ホームディレクトリ拡張などの他のシェル機能に簡単にアクセスしたい場合一緒に行うことができます。便利です。 。

したがって、次のように指定すると方法が機能します。

subprocess.call("sed s'/2\.6/2.6.4/g' /tmp/file.xml", shell=True)

しかし...

警告するshell=True使用時に安全上の危険があります。
信頼できないソースからの洗練されていない入力を含むシェルコマンドを実行すると、プログラムは攻撃に対して脆弱になります。シェル注入、任意のコマンドの実行につながる可能性がある深刻なセキュリティの脆弱性です。このshell=Trueためとても落胆 コマンド文字列が外部入力として構成されている場合。

shell=Trueを使用すると、pipes.quote()シェルコマンドの設定に使用される文字列の空白と、シェルメタ文字を正しくエスケープするために使用できます。

結論:コマンドをargs単一の文字列(shell=Trueset)に渡す場合は、少なくともエスケープ/引用符を付ける必要があります。ただし、上記のようにさまざまなパラメータを提供することをお勧めします。

import subprocess

subprocess.call(['sed', 's/2\.6/2.6.4/g', '/tmp/file.xml'])

関連情報