Python変数の値をbashスクリプトに転送する(Pythonスクリプト内)

Python変数の値をbashスクリプトに転送する(Pythonスクリプト内)

長年のbashスクリプトの最後に、特定の条件が満たされたときにシェルスクリプトを呼び出すようにPythonスクリプトを変更することができました。この部分は大丈夫です。しかし、Pythonスクリプトからこのシェルスクリプトに変数を送信しようとしています。

シェルスクリプトはstdinを使用しますが、ここに整数のPython変数の値を入れようとしています。

私のコードは(今まで)次のようになります。

if VAR > NUMBER:
import os
bashCommand = "echo something | /path/to/script --args"
os.system(bashCommand) 

そしてそれは素晴らしい作品です。しかし、私が望むのは、os.system(bashCommand)を次のようにすることです:

echo $VAR | /path/to/script --args

でも

echo 'some text' $VAR | /path/to/script --args

os.systemの動作方法を考えると、私のアプローチは完全に間違っているようです。

だから私の質問は、VARの値をbashCommandに、好ましくは標準入力に渡す方法です。

答え1

使用しないでくださいos.system()。モジュールには使用されなくなりましたsubprocess

モジュールを直接使用できますが、シェルから直接コマンドを実行するのは安全ではないため、subprocessこのパラメータを使用しないことをお勧めします。shell=True必要なすべての機能(パイプなど)をモジュールsubprocessとしてシミュレートできます。

この例を見てみましょう。

import subprocess
var = 'foobar'

first = subprocess.Popen(['/bin/echo', var], stdout=subprocess.PIPE)
second = subprocess.Popen(['bash', '/path/to/script', '--args'], stdin=first.stdout)

変数を定義しvar、そのクラスを使用してsubprocess.Popen値を取得し、その値をパイプに送信します。これは授業の対象です。var/bin/echofirstsubprocess.Popen

次に、viaパイプのSTDOUTをSTDINとして使用し、firstそれに応じてスクリプトを実行します。secondbash

コマンドの出力を文字列として保存するには、subprocess.check_output次の関数を使用します。

second = subprocess.check_output(['bash', '/path/to/script', '--args'], stdin=first.stdout)

読むサブプロセスモジュールの公式文書より多くのアイデアを得るために。

答え2

Pythonはbashのように文字列の変数を拡張しません。 Pythonがあり、VARそれをbashに渡すには、次のようにします。

subprocess.call('echo {} | /path/to/script --args'.format(VAR), shell=True)

VAR拡張したいbash変数の名前がPythonに保存されている場合は、次のようにできます。

subprocess.call('echo "${}" | /path/to/script --args'.format(VAR), shell=True)

答え3

呼び出しはos.system()廃止されましたが、まだ機能します。この機能は将来消えてしまう可能性があるため、subprocessサブプロセスのSTDINにデータを送信し、そのSTDOUTから読み取る非常に簡単な方法を持つモジュールを使用してこれらの呼び出しをリファクタリングすることを真剣に検討できます。https://docs.python.org/2/library/subprocess.html

答え4

私の考えに良いアプローチは次のとおりです。

var = subprocess.Popen(['/bin/echo', var], stdout=subprocess.PIPE)
second = subprocess.Popen(['bash', '/path/to/script', '--args'],stdin=var.stdout, stdout=subprocess.PIPE)
var.stdout.close()
output = second.communicate()[0]
var.wait()

関連情報