Posted at

[Python] unixコマンドを実行する(subprocess)

More than 3 years have passed since last update.


設定

環境:

OSX Yosemite

Bash

Python3.5.0

Python上でUnixコマンドの出力を獲得したい.

※ShellScript等書いたほうが早いです.


Unixコマンド

MacのOSXはUNIXがベースになっているのでそれ使います.(ls, touch, cat等)


os.system

標準ライブラリos

こちらでも,Unixコマンドは使えるのですが,返り値が文字列として得られないのです.(得られるかもしれないけど知らない)(Terminalに出力されるだけ)

普通に,touch等のコマンドのファイル操作系であれば、コチラだけで用が足りる.

cat,grep等のコマンドである場合,文字列として得られないのです.


subprocess

参考にしたリンクはこちら

17.5. subprocess — サブプロセス管理

この中のsubprocess.check_outputを使います。

使い方としては、引数に文字列を入れるわけですが、二通りあって、まず、デフォルトで使う場合には、

check_output(["cut", "-d", "test.txt"])

とします。

もう一つは、引数にshell=Trueを使うことで、文字列を渡すと実行できるようになり、

check_output("cut -d test.txt", shell=True)

詳しくは参考にしたURLにこう書いてあります。


Unix で shell=False の場合 (デフォルト): この場合、 Popen クラスは子プログラムを実行するのに os.execvp() を使います。 文字列が引数として与えられた場合、実行されるプログラムの名前かパスとして使われます;ただし、プログラムは引数無しの場合のみ動作します。



Unix で shell=True の場合: args が文字列の場合、シェルを介して実行されるコマンドライン文字列を指定します。文字列は厳密にシェルプロンプトで打つ形式と一致しなければなりません。例えば、文字列の中にスペースを含むファイル名がある場合、はクォーティングかバックスラッシュエスケープが必要です。 args が文字列の場合には最初の要素はコマンド名を表わす文字列としてそして残りの要素は続く引数としてシェルに渡されます。これは、以下の Popen と等価ということです。



簡単なサンプル

適当にファイル作って、2列目を獲得する(cut -d, -f2)サンプルです。

3系なのでbytesで値が帰ってきます。(str返してくれるオプション(キーワード引数)ありそうだけど)

3系の場合、返ってくるのがbytesなので、コードの最後にありますが、universal_newlines=Trueつけるとstrで返ってきます。


subprocess_test.py

>>> open("test.txt", 'w').write('\n'.join(([repr([i, i+1, i+2]).replace(' ', '') for i in range(5)])))

39
>>> open("test.txt").read()
'[0,1,2]\n[1,2,3]\n[2,3,4]\n[3,4,5]\n[4,5,6]'
>>>
>>> import subprocess
>>> subprocess.check_output(["cut", "-d,", "-f2", "test.txt"])
b'1\n2\n3\n4\n5\n'
>>> subprocess.check_output("cut -d, -f2 test.txt", shell=True)
b'1\n2\n3\n4\n5\n'
>>> subprocess.check_output("cut -d, -f2 test.txt", shell=True, universal_newlines=True)
'1\n2\n3\n4\n5\n'


まとめ

大体、ShellScript書いたほうが早いですが、参考までにPythonでUnixコマンドの実行方法を書きました。