Pythonからの外部コマンドの実行


この章では、Pythonから外部コマンドをどのように実行するか、出力と他の関連する詳細を終了ステータスなどをキャプチャする方法について説明します.コマンドの可用性はあなたが使っているOSに依存します(私のものはLinuxです).

osモジュールの使用
最後の章ではos ファイル処理用のモジュールです.The os モジュールは、外部コマンドを操作するためのインターフェイスを提供するような他の用途の多くの機能豊富なモジュールです.以下に例を示します:
>>> import os

>>> os.system('echo hello "$USER"')
hello learnbyexample
0
このprint() 関数は、外部コマンドの出力があれば画面に表示される.返り値はコマンドの終了ステータスです.0 コマンドが正常に実行されたことを意味します.につきdocs.python: os.system :

On Unix, the return value is the exit status of the process encoded in the format specified for wait().


以下に0の終了ステータスの例を示します:
>>> status = os.system('ls xyz.txt')
ls: cannot access 'xyz.txt': No such file or directory
>>> status
512
# to get the actual exit value
>>> os.waitstatus_to_exitcode(status)
2

# if you don't want to see the error message,
# you can redirect the stderr stream
>>> os.system('ls xyz.txt 2> /dev/null')
512
あなたはos.popen() 外部コマンドの結果を保存する方法.read ( default )とwriteの両方のファイルオブジェクトを提供します.ステータスをチェックするにはclose() ファイルハンドルのメソッドNone は成功を意味する).
>>> fh = os.popen('wc -w <ip.txt')
>>> op = fh.read()
>>> op
'9\n'
>>> status = fh.close()
>>> print(status)
None

# if you just want the output
>>> os.popen('wc -w <ip.txt').read()
'9\n'

サブプロセスラン
The subprocess モジュールは、より冗長で安全なオプションを外部コマンドを実行します.
関連部品の引用doc.python: subprocess module :

The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.

The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases, the underlying Popen interface can be used directly.


>>> import subprocess

>>> subprocess.run('pwd')
'/home/learnbyexample/Python/programs/'
CompletedProcess(args='pwd', returncode=0)

>>> process = subprocess.run(('ls', 'xyz.txt'))
ls: cannot access 'xyz.txt': No such file or directory
>>> process.returncode
2
最初の引数run() メソッドは実行するコマンドです.これは、単一の文字列または文字列のシーケンスであることができます(実行中のコマンドに引数を渡す必要がある場合).デフォルトでは、コマンド出力が画面に表示されます.返り値CompletedProcess オブジェクトは、終了ステータスのような実行されたコマンドに関連する情報を持っています.
運動としてsubprocess.run documentation と上記のls 以下に例を示します:
  • リダイレクトstderr ストリーム/dev/null
  • 終了ステータスがゼロでないときに自動的に例外を送出する
  • 参考:
  • stackoverflow: How to execute a program or call a system command from Python?
  • stackoverflow: difference between subprocess and os.system
  • stackoverflow: How to use subprocess command with pipes
  • stackoverflow: subprocess FAQ

  • シェル= true
    また、os.system() , あなたがセットするならばshell キーワード引数True . これは便利ですが、あなたの個人的なスクリプトなどの実行されているコマンドを完全に制御する場合にのみ使用します.さもなければ、それはセキュリティ問題につながることができますstackoverflow: why not use shell=True 詳細は
    引用docs.python: subprocess Frequently Used Arguments :

    If shell is True, the specified command will be executed through the shell. This can be useful if you are using Python primarily for the enhanced control flow it offers over most system shells and still want convenient access to other shell features such as shell pipes, filename wildcards, environment variable expansion, and expansion of ~ to a user's home directory


    >>> p = subprocess.run(('echo', '$HOME'))
    $HOME
    >>> p = subprocess.run('echo $HOME', shell=True)
    /home/learnbyexample
    
    >>> p = subprocess.run(('ls', '*.txt'))
    ls: cannot access '*.txt': No such file or directory
    >>> p = subprocess.run('ls *.txt', shell=True)
    ip.txt
    
    >>> p = subprocess.run('seq -s, 10 > out.txt', shell=True)
    >>> p = subprocess.run('cat out.txt', shell=True)
    1,2,3,4,5,6,7,8,9,10
    
    If shell=True 使用できませんが、上記のようにシェルの機能が必要です.os , glob , shutil などが当てはまる.参考docs.python: Replacing Older Functions with the subprocess Module .
    >>> p = subprocess.run(('echo', os.getenv('HOME')))
    /home/learnbyexample
    

    シェルの変更
    デフォルトでは/bin/sh はPOSIXシステムのシェルである.を設定することによって変更することができますexecutable あなたの選択のシェルへの引数.
    >>> p = subprocess.run('diff <(seq 3) <(seq 4)', shell=True)
    /bin/sh: 1: Syntax error: "(" unexpected
    
    >>> p = subprocess.run('diff <(seq 3) <(seq 4)', shell=True,
                           executable='/bin/bash')
    3a4
    > 4
    

    キャプチャ出力
    あなたが使うならばcapture_output=True , the CompletedProcess オブジェクトはstdout and stderr 同様に結果.これらはbytes デフォルトでデータ型.設定で変更できますtext=True .
    >>> p = subprocess.run(('date', '-u', '+%A'), capture_output=True, text=True)
    >>> p
    CompletedProcess(args=('date', '-u', '+%A'), returncode=0,
                     stdout='Monday\n', stderr='')
    >>> p.stdout
    'Monday\n'
    
    また、使用することができますsubprocess.check_output() 出力を直接取得するメソッドです.
    >>> subprocess.check_output(('date', '-u', '+%A'), text=True)
    'Monday\n'
    

    You can also use legacy methods subprocess.getstatusoutput() and subprocess.getoutput() but they lack in features and do not provide secure options. See docs.python: subprocess Legacy Shell Invocation Functions for details.