Python の subprocess で、実行時のディレクトリを指定する方法です。
Python からコマンドラインツールを呼び出すときに、現在のフォルダ(ディレクトリ)を変更して実行したい時があります。
『cd コマンドで、フォルダを移動してから実行するように、フォルダを指定してから実行したい。』
どのようにしたらいいのか?
フォルダを指定して実行するときは、引数 cwd にフォルダのパスを渡します。
具体的には、
subprocess.run(cmd, cwd=r"フォルダパス")
とか、
subprocess.Popen(cmd, cwd=r"フォルダパス")
のように指定したら、うまくいきました。
以下、コード例の全体と解説です。
フォルダを指定して subprocess.run()
subprocess.run() のコード例
subprocess.run() で、実行するときのフォルダを指定して呼び出すコード例です。
cd コマンドを実行することで、実行時のフォルダをチェックします。
"""フォルダ(ディレクトリ)を指定して実行するコード例 subprocess.run"""
from subprocess import run, PIPE
# Pythonファイルの場所を表示
print('__file__: %s\n' % __file__)
# ■ フォルダを指定せずに実行
folder1 = None
a = run('cd', stdout=PIPE, shell=True, cwd=folder1,
universal_newlines=True, timeout=10)
print('cwd=%s' % folder1)
print(' stdout: %s' % a.stdout)
# ■ フォルダを指定して実行
folder2 = r'D:\\'
a = run('cd', stdout=PIPE, shell=True, cwd=folder2,
universal_newlines=True, timeout=10)
print('cwd=%s' % folder2)
print(' stdout: %s' % a.stdout)
subprocess.run() の実行結果
標準出力に、cwd で指定したフォルダが返って来ました。
subprocess.run() で実行した cd コマンドが、指定したフォルダで実行された、ということがわかります。
F:\apps>python F:\apps\subprocess_run.py
__file__: F:\apps\subprocess_run.py
cwd=None
stdout: F:\apps
cwd=D:\\
stdout: D:\
コード例の解説
まず、フォルダが変わったことをどうやって確認するのか?
Windows の場合ですが、現在のフォルダは、コマンドプロンプトの cd コマンドで取得できます。
普段、フォルダの移動に使っている cd コマンドですが、引数なしで使うと、現在のフォルダを標準出力 (stdout) に出してくれます。
cwd を指定しながら cd コマンドを実行することで、フォルダが変わったことを確認します。
次に、subprocess.run() と subprocess.Popen() のところの解説です。
stdout=PIPE
は、標準出力の内容を受け取るために指定しています(指定しないと標準出力がNoneになった)。
shell=True
は、cd コマンドを使うために指定しています(指定しないと cd コマンドが実行できなかった)。ふつう、subprocess で外部プログラムを呼び出すときは、shell=False
で動きました。
universal_newlines=True
は、標準出力を文字列型として取得するために指定しています(Falseだと標準出力がbyte型になった)。
timeout=10(秒)
は、必要に応じて指定します(指定しなくても実行可能)。
subprocess — サブプロセス管理 -Python ドキュメント
フォルダを指定して subprocess.Popen()
subprocess.Popen() のコード例
subprocess.Popen() で、実行するときのフォルダを指定して呼び出すコード例です。
cd コマンドを実行することで、実行時のフォルダをチェックします。
"""フォルダ(ディレクトリ)を指定して実行するコード例 subprocess.Popen"""
from subprocess import Popen, PIPE, TimeoutExpired
# Pythonファイルの場所を表示
print('__file__: %s\n' % __file__)
# ■ フォルダを指定せずに実行
folder1 = None
p = Popen('cd', stdout=PIPE, shell=True, cwd=folder1,
universal_newlines=True)
try:
(stdout, stderr) = p.communicate(timeout=10)
except TimeoutExpired:
p.kill()
(stdout, stderr) = p.communicate()
print('cwd=%s' % folder1)
print(' stdout: %s' % stdout)
# ■ フォルダを指定して実行
folder2 = r'D:\\'
p = Popen('cd', stdout=PIPE, shell=True, cwd=folder2,
universal_newlines=True)
try:
(stdout, stderr) = p.communicate(timeout=10)
except TimeoutExpired:
p.kill()
(stdout, stderr) = p.communicate()
print('cwd=%s' % folder2)
print(' stdout: %s' % stdout)
subprocess.Popen() の実行結果
標準出力に、cwd で指定したフォルダが返って来ました。
subprocess.Popen() で実行した cd コマンドが、指定したフォルダで実行された、ということがわかります。
F:\apps>python F:\apps\subprocess_popen.py
__file__: F:\apps\subprocess_popen.py
cwd=None
stdout: F:\apps
cwd=D:\\
stdout: D:\
以上です。