Pythonコードからシェルスクリプトを呼び出す方法


回答:


252

サブプロセスのモジュールは、あなたを助けます。

非常に些細な例:

>>> import subprocess
>>> subprocess.call(['./test.sh']) # Thanks @Jim Dennis for suggesting the []
0 
>>> 

どこにtest.sh簡単なシェルスクリプトで、0この実行のために、その戻り値です。


11
注:文字列ではなくsubprocess.call()にリストを渡すことをお勧めします(例と理由については、下記のHugo24のコマンドを参照してください)。
ジム・デニス

1
チュートリアルへのリンクが壊れています。
Kshitij Saraogi 2017年

6
これにより、OSError:[Errno 13]権限が拒否されました。スクリプトをsudoで実行する必要はありません。@Manoj Govindan
alper

6
引数あり:subprocess.call(['./ test.sh'、 'param1'、 'param2'])
Henry

2
@alperは、スクリプトを配置したフォルダーに移動し、コマンドを実行し chmod +x script.shます。注:script.shはスクリプトのプレースホルダーです。適宜置き換えてください。
トムJムティレンティ

105

os.popen()(非推奨)またはsubprocessモジュール全体を使用するいくつかの方法がありますが、このアプローチ

import os
os.system(command)

最も簡単なのです。


1
なぜこれが最も賛成された答えではないのですか?モジュールをインポートする必要はありませんか?ここにいくつかの欠点があるのでしょうか?
boulder_ruby 2016年

6
を使用しsubprocessて、入力/出力/エラーパイプを管理できます。引数が多い場合にも優れています。引数の簡単なリストがあるためos.command()、特殊文字をエスケープしてコマンドライン全体を作成する必要がsubprocessあります。ただし、単純なタスクでos.command() は十分な場合があります。
のMichałニクラス

1
そのリンクから引用するには:The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*
Maximilian

42

シェルスクリプトにいくつかのパラメーターを渡したい場合は、メソッドshlex.split()を使用できます。

import subprocess
import shlex
subprocess.call(shlex.split('./test.sh param1 param2'))

test.sh同じフォルダにあります:

#!/bin/sh
echo $1
echo $2
exit 0

出力:

$ python test.py 
param1
param2

これはエレガントです。
カレブ


15

上記のサブプロセスモジュールを使用します。

私はそれを次のように使用します:

subprocess.call(["notepad"])

13
注:リストを使用してサブプロセスを呼び出すと、解析/解釈のために(無害化されていない可能性がある)文字列をシェルに渡す必要がないため、より安全です。リストの最初の項目は実行可能ファイルであり、他のすべての項目は引数として渡されます。
ジム・デニス

13

Python 3.5を実行していますが、subprocess.call(['./ test.sh'])が機能しません。

出力で何をしたいかに応じて、3つのソリューションを提供します。

1-スクリプトを呼び出します。端末に出力が表示されます。出力は数値です。

import subprocess 
output = subprocess.call(['test.sh'])

2-実行とエラーを呼び出して文字列にダンプします。print(stdout)を実行しない限り、ターミナルでの実行は表示されません。Popenの引数としてのShell = Trueは私には機能しません。

import subprocess
from subprocess import Popen, PIPE

session = subprocess.Popen(['test.sh'], stdout=PIPE, stderr=PIPE)
stdout, stderr = session.communicate()

if stderr:
    raise Exception("Error "+str(stderr))

3-スクリプトを呼び出し、temp_fileにtemp.txtのエコーコマンドをダンプします

import subprocess
temp_file = open("temp.txt",'w')
subprocess.call([executable], stdout=temp_file)
with open("temp.txt",'r') as file:
    output = file.read()
print(output)

docサブプロセスを確認することを忘れないでください


1
stdout = PIPEまたはstderr = PIPEをと共に使用しないでくださいsubprocess.call。パイプが読み取られていないために、OSプロセスのパイプバッファーを満たすのに十分な出力をパイプに生成すると、子プロセスはブロックします。

4

サブプロセスモジュールは、サブプロセスを起動するのに適したモジュールです。これを使用して、次のようにシェルコマンドを呼び出すことができます。

subprocess.call(["ls","-l"]);
#basic syntax
#subprocess.call(args, *)

あなたはここでそのドキュメントを見ることができます。

スクリプトが.shファイルまたは長い文字列で記述されている場合は、os.systemモジュールを使用できます。それはかなりシンプルで簡単に呼び出すことができます:

import os
os.system("your command here")
# or
os.system('sh file.sh')

このコマンドは、スクリプトを1回実行して完了し、終了するまでブロックします。


sysもインポートする必要はありませんか?
ScottyBlades

いいえ、必要ありません。Pythonシェルを開いてこのスニペットを実行してみてください
Descartes

4

スクリプトに複数の引数がある場合

#!/usr/bin/python

import subprocess
output = subprocess.call(["./test.sh","xyz","1234"])
print output

出力にステータスコードが表示されます。スクリプトが正常に実行されると、0が返されます。それ以外の場合はゼロ以外の整数が返されます。

podname=xyz  serial=1234
0

以下はtest.shシェルスクリプトです。

#!/bin/bash

podname=$1
serial=$2
echo "podname=$podname  serial=$serial"

2

サブプロセスは良いですが、一部の人々はより良いスクリプトを好むかもしれません。Scriptineには、shell.call(args)path.rename(new_name)、およびpath.move(src、dst)などのより高レベルのメソッドセットがあります。Scriptineはサブプロセスなどに基づいています。

Scriptineの2つの欠点:

  • 現在のドキュメントレベルは、それで十分であっても、より包括的です。
  • サブプロセスとは異なり、scriptineパッケージは現在デフォルトではインストールされません。

2

私はこれが古い質問であることを知っていますが、最近この問題に遭遇し、Python 3.5以降に変更されたサブプロセス API から誤解してしまいました。

外部スクリプトを実行する新しい方法runは、argsで記述されたコマンドを実行する関数を使用する方法です。コマンドが完了するのを待ってから、CompletedProcessインスタンスを返します。

import subprocess

subprocess.run(['./test.sh'])

1

シェルスクリプトファイルに実行権限がない場合は、次のように実行します。

import subprocess
subprocess.run(['/bin/bash', './test.sh'])

-9

次のコードを試してください:

Import Execute 

Execute("zbx_control.sh")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.