Pythonスクリプトでbashコマンドを実行する方法


回答:


15

@milneの答えは機能しsubprocess.call()ますが、フィードバックはほとんどありません。

subprocess.check_output()stdoutに出力された内容を分析できるように、使用することを好みます。

 import subprocess
 res = subprocess.check_output(["sudo", "apt", "update"])
 for line in res.splitlines():
     # process the output line by line

check_output 呼び出されたコマンドのゼロ終了時にエラーをスローします

してください、これは起動しないことに注意してくださいbashまたは別のシェルを指定しない場合はshell関数にキーワード引数を(同じことが当てはまりますsubprocess.call()、そしてあなたはそれがセキュリティ上の危険を強いるよう必要はありませんが、必要がない場合)、それが直接起動しますコマンド。

Pythonから多くの(異なる)コマンド呼び出しを実行していることに気付いた場合は、plumbumを調べてください。それにより、より読みやすい(IMO)を行うことができます。

from plumbum.cmd import sudo, apt, echo, cut

res = sudo[apt["update"]]()
chain = echo["hello"] | cut["-c", "2-"]
chain()

os.popenまたはos.system)を使用することをお勧めしますres = os.popen('sudo apt update').read()。例:?@Anthon
アルパース

1
読む0324 @alper python.org/dev/peps/pep-0324。これは、作成の理由を説明しますsubprocessos.systemos.popenすでに存在します。このようなPEPは受け入れられるのは簡単なことではありません。いくつかの人々は、あなたや私が今まで意志よりもはるかに多くのことを考えて与えています。そして、subprocess2003年以降改善されている、他の人は、下位互換性のためだけ残っています。あなたが赤の持っているos.systemマニュアルページ:subprocessモジュールは、新しいプロセスを生成し、その結果を取得するためのより強力な機能を提供します。そのモジュールを使用してこの機能を使用することが好ましいです。
アントン

1
@alperはい、できます。これは潜在的なセキュリティ上の危険であると指摘したので、なぜそれが推奨されると思うのかわかりません。そして、呼び出しsudoはそれをより厳しくするだけです。たぶんpython-aptを使用する方がより良い解決策です(私はそれを自分で調べたことはありません)。
アントン

1
その場合の@alperはplumbumを真剣に検討し、それに立ち向かう価値があります。
アントン

1
@alper Python3を使用している場合、Python2を使用する必要はありません。ここでのコメントはチャットシステムとして使用しないでください。質問がある場合は、そのように投稿してください。
アントン

8

コマンドを実行するためのパラメーター-cを使用して、bashをプログラムとして使用することができます。

例:

bashCommand = "sudo apt update"
output = subprocess.check_output(['bash','-c', bashCommand])

6

サブプロセスモジュールは、これを行うために設計されています。

import subprocess
subprocess.call(["sudo", "apt", "update"])

コマンドが失敗した場合に終了するスクリプトをご希望の場合は、使用して検討するかもしれないcheck_call()代わりに、戻りコードを自分で解析します:

subprocess.check_call(["sudo", "apt", "update"])

これは私に次のようなトレースバックを与えた:Traceback (most recent call last): File "/home/Dremor/test.py", line 3, in <module> subprocess.call('sudo', 'yum', 'update') File "/usr/lib64/python3.4/subprocess.py", line 537, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib64/python3.4/subprocess.py", line 767, in __init__ raise TypeError("bufsize must be an integer") TypeError: bufsize must be an integer (私はメインOSとしてFedoraのを使用していて、私はyumを使用しています)
Dremor

3
あなたは角括弧を忘れてしまった
本部Milind Dumbare

1
また、subprocess.call()ブロックされてsubprocess.Popen()いる
のに

「ブロック」とはどういう意味ですか?@heemayl
alper

2

また、「os.popen」を使用できます。

例:

import os

command = os.popen('ls -al')
print(command.read())
print(command.close())

出力:

total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None

0

サブプロセスモジュールを使用

import subprocess
command = 'sudo apt update'
subprocess.check_call(command.split())

使用時にエラーが発生する理由
アクアグレムリン

subprocess.check_call([ "須藤"、 "傾向"、 "更新"])
aquagremlin

CalledProcessErrorトレースバック(最後の最後の呼び出し)<ipython-input-21-33ce645708e7> in <module>()----> 1 subprocess.check_call(["sudo"、 "apt"、 "update"])/ usr / lib_python2.7 / subprocess.pyc in check_call(* popenargs、** kwargs)188 cmdがNoneの場合:189 cmd = popenargs [0]-> 190 raise CalledProcessError(retcode、cmd)191 return 0 192 CalledProcessError:Command '[' sudo '、' apt '、' update ']'はゼロ以外の終了ステータス1を
返しました

このエラーは、jupyterノートブックで実行した場合にのみ発生します
アクアグレムリン

多分私はこれがotであるので新しい質問を始めます
アクアグレムリン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.