4

Pythonのサブプロセスモジュールで遊んでいて、いくつかの例を試しましたが、ヒアドキュメントステートメントを機能させることができないようです。

これが私が遊んでいた些細な例です:

import subprocess
a = "A String of Text"
p = subprocess.Popen(["cat", "<<DATA\n" + a + "\nDATA"])

上記のコードを実行すると、次のエラーが発生します。

cat: <<DATA\nA String of Text\nDATA: No such file or directory

私はそれを間違っていますか?これも可能ですか?もしそうなら、私はそれをどのように行うのですか?


アップデート

これを行うためのより良い方法があるので、これは実際のPythonプログラムでは決して実行されるべきではないと言いたかっただけです。

4

4 に答える 4

6

シェルの「ヒアドキュメント」サポートはシェル機能です。subprocess.Popenデフォルトではシェルを介してコマンドを実行しないため、この構文は確かに機能しません。

ただし、とにかくパイプを使用しているので、シェルのヒアドキュメントサポートを使用する必要はありません。a開始したばかりのプロセスのstdinパイプに文字列を書き込むだけです。これは、とにかくシェルがヒアドキュメントで行うこととまったく同じです。

あなたはこれを行うことができますPopen.communicate()

p.communicate(a)

関数の戻り値にはcommunicate()、プロセスの出力が含まれます(2つのストリームで、ドキュメントを参照してください)。

于 2009-09-03T21:33:35.923 に答える
4

他の人が指摘しているように、シェルで実行する必要があります。Popenは、shell=True引数を使用してこれを簡単にします。次の出力が得られます。

>>> import subprocess
>>> a = "A String of Text"
>>> p = subprocess.Popen("cat <<DATA\n" + a + "\nDATA", shell=True)
>>> A String of Text

>>> p.wait()
0
于 2009-09-03T21:58:11.573 に答える
3

catシェル構文を引数としてプログラムに渡します。あなたはそのようにそれを試みることができます:

p = subprocess.Popen(["sh", "-c", "cat <<DATA\n" + a + "\nDATA"])

しかし、概念自体は間違っています。Pythonスクリプト内でシェルスクリプトを呼び出す代わりに、Python機能を使用する必要があります。

この特定のケースでは、シェルのヒアドキュメント構文が変数を補間する必要があるため、内部のすべてのテキストをエスケープして、その中に行aがないことを確認する必要がありDATAます。


print(a)Pythonに相当するものの場合、これに最も近いアイデアは( ;-))、生成されたプロセスのstdinに変数の値を渡すことだと思います。

p = subprocess.Popen(["program", ...], stdin=subprocess.PIPE)
p.communicate(a)
于 2009-09-03T21:37:49.703 に答える
0

Python 3.5以降、次のようにsubrocess.runを使用できます。

subprocess.run(['cat'], input=b"A String of Text")
于 2021-05-12T15:57:07.070 に答える