一部修正しました(取り消し線部)
一連のコマンドを走らせたかったのですが、私はシェルスクリプトの文法が苦手です。そこで、Python 3でシェルのコマンドを実行させる方法を調べてみました。書きやすいし、より高級なことができると思います。
subprocess
モジュール
他にも何かあるみたいですが、現在はsubprocess
モジュールのrun()
関数を用いるのが推奨されているようです。Python 3.5で追加されたほやほやの関数です。
以下のようにすると$ ls -l /usr/bin
を実行できます。
cmd = ['ls', '-l', '/usr/bin']
subprocess.run(cmd)
結果は標準出力に出力されます。結果をプログラム内で使いたい場合は引数にstdout=subprocess.PIPE
を追加してください。run()
の返り値はCompletedProcess
クラスです。そのstdout
属性にはバイト列として格納されているので適宜デコードしてください。以下は同じ出力がされます。
cmd = ['ls', '-l', '/usr/bin']
out = subprocess.run(cmd, stdout=subprocess.PIPE)
print(out.stdout.decode())
piyo of hoge.txt
のようなスペースを含むファイル名を(コマンドライン)引数にとっても適切にエスケープクォートしてくれます。ただ、~
(ホーム)や*
のようなワイルドカードは(エスケープされるためか)もクォートされてしまい期待した通りいかないのでos.path.expanduser()
やglob.glob()
を使えばいいと思います。
引数にshell=True
をとるとそういった展開もやってくれますが危険なのでやめた方がいいらしいです(シェルインジェクション)。こわいこわい。
cmd = 'ls -l /usr/bin'
subprocess.run(cmd, shell=True)
(この場合は逆に、スペースやダメ文字メタ文字を含むファイル名はこちらでエスケープしてやる必要がありますが、)単一の文字列で渡せるのはいいなと思います。shell=False
では以下のように改行してやれば見やすい気がします。タイプは依然めんどくさいですけど。
cmd = [
'command',
'--hikisuu-nashi-option',
'-o', 'hikisuu',
]
1行目に以下のshebangを書き、実行権限を付けてパスの通ったところにおけばオリジナルコマンドが作れますね。
#!/usr/bin/env python3
うん、これでbashの文法覚えずに済む。