IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

ゼロから歩くPythonの道

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes 

第47回 Pythonのsubprocessモジュールでコマンドプロンプトを起動してみた (菱沼佑香) 2023年11月

こんにちは、吉政創成 菱沼です。
今回も「きれいなPythonプログラミング(マイナビ出版)」という書籍を利用して学習します。

さて、いまは2章の「環境設定とコマンドライン」を学習中です。
前回はPythonをコマンドラインで実行する方法を学びました。今回はPython側からコマンドを実行する方法と、コマンドの便利機能について学びます。

Pythonで書いたプログラムからコマンドを実行する方法

コマンドプロンプトからPythonのプログラムを実行できるなら、その逆もありということで。
Pythonの標準ライブラリにあるsubprocessモジュールを使うと、Pythonプログラムから、他のアプリやコマンドを起動できるのだそうです。

-----
P.28
Subprocessモジュールのsubprocess.run()関数は、Pythonプログラム内でシェルコマンドを実行し、そのコマンドの出力を文字列として表示することができます。例えば、次のコードではls -alコマンドを実行しています。


import subprocess, locale
import locale
procObj = subprocess.run([’ls’, ’-al’], stdout=subprocess.PIPE)
outputStr = procObj.stdout.decode(locale.getdefaultlocale()[1])
print(outputStr)

subprocess.run()に[’ls’, ’-al’]のリストを渡します。このリストには、コマンド名lsとそれに続く引数が個々の文字列として含まれています。[’ls’, ’-al’]を渡しても動作しないので注意してください。次に、コマンドの出力を文字列としてoutputStrに格納します。subprocess.run()とlocale.getdefaultlocale()のオンラインドキュメントを見れば、これらの関数がどのように動作するかがよくわかると思いますが、これらの関数はPythonが動作するあらゆるOSコードを動作させます。
-----

ということで、実行してみたのですが、私の環境ではこのコードだとエラーになりました。
なんでかなーと調べてみると、エラーの理由はどうやら2つある模様。

  1. Windowsではlsコマンドをデフォルトのままでは使えないため、dirコマンドに変える
  2. dirコマンドは、シェルからしか使えないため、shell=Trueを追加する

これを受けて以下のようにコードを変えてみました。

fig01

結果はコマンドプロンプトでdirコマンドを実行したものと同じ内容でした。

ところで、shell=Trueに関しては外部プロセスがシェル上で実行されることになるため、悪意のあるコマンドやコードを実行されるという脆弱性につながることもあるため、なるべく使わない方がいいそうです。もしshell=Trueをどうしても使いたい場合には、空白文字やメタ文字などの特殊文字を引用符で囲ったりエスケープ処理をしたりといった処理が必要とのこと。

では、使わないにしてもどうすればいいかと言えば、dirの部分を、[’cmd’, ’/c’, ’dir’]に変えてあげればいいようです。

fig02

こうすることで、コマンドプロンプトを起動すること、/cオプションは、この後に続くコマンドを実行した後にコマンドプロンプトを終了するという意味になるそうです。実行したら確かに同じ結果となりました。

参考サイト
subprocess --- サブプロセス管理|公式マニュアル
pythonからterminalを操作する (subprocess)
Windowsコマンド集
Python基礎15:サブプロセス管理(subprocess)

入力補助機能で、黒い画面と上手なお付き合い

ところで、黒い画面を華麗に操るエンジニアやプログラマーを横から眺めていると、やたら早いと思ったことはありませんか。目で追うのたいへーんと思っていたら、どうやら入力を補助する機能が備わっているそうです。

タブ補完機能

-----
P.28
上級者は1日に何時間もコンピューターにコマンドを入力するので、最近のコマンドラインには、入力量を最小限にするための機能が備わっています。タブ保管機能(コマンドライン保管、オートコンプリートとも呼ばれることもあります)は、ユーザーがフォルダーやファイル名の最初の数文字を入力し、TABキーを押すと、シェルが残りの名前を埋めてくれる機能です。
例えば、Windowsでcd c:¥uと入力してTABキーを押すと、c:¥uで始まるフォルダーやファイルをチェックして、C:¥Usersのように保管してくれます。小文字のuもUに修正されます(macOSやLinuxでは、タブ補完では大文字小文字の訂正は行われません)。c:¥フォルダー内にuで始まるフォルダーやファイル名が複数ある場合は、TABキーを押し続けることで、すべてのフォルダーやファイルを循環することが出来ます。さらに、c:¥usと入力すると、usで始まるフォルダーやファイル名を絞り込むことができます。
TABキーを複数回オスと、macOSやLinuxでも動作します。
--------

実際に試してみるとこんな感じです。uだと他の候補があまりないのでさらにその下のディレクトリで試してます。TABキーを押すたびに、次の候補が順番に出てきます。

fig03

カレントディレクトリ内のフォルダーなら、表示したいフォルダーの頭文字、例えばDなら、[cd D]でDがつくフォルダーだけが表示されます。

ところで、頭文字を忘れたという事も、もちろんあると思います。この場合、[cd ]でTABキーを押すと、カレントディレクトリにあるフォルダーを順番に出してくれるみたいです。

fig04

さらにさらに、流れ作業でやってて、うっかり通り過ぎちゃったという事もあると思いますが、ずっとTABキーを押してそれがまた出てくるまでやるなんて面倒です。そんな時はShift+TABキーで一つ前に戻れます。

コマンド履歴の表示

ちょっと打ち間違えた...とか、同じような作業を繰り返したいとき、一から入力しなおすのは面倒くさいですよね。どうやら履歴が使えるようです。

-----
P.29
最近のシェルは、入力されたコマンドを履歴として記憶しています。ターミナルで上矢印キーを押すと、直前に入力したコマンドがコマンドラインに表示されます。上矢印キーを押し続けるとさらに前のコマンドが表示され、下矢印キーを押すと最近のコマンドに戻ることができます。現在プロンプトに表示されているコマンドをキャンセルして、新しいプロンプトから始めたい場合は、CTRL+Cキーを押してください。
Windowsでは、doskey /historyを実行するとコマンド履歴を見ることができます。(中略)macOSやLinuxでは、historyコマンドを実行することで、コマンド履歴を見ることができます。
------

ということで、やってみました。

fig05

確かに入力したコマンドがすべて表示されていました。

それではきりが良いので、今回はここで終了です。お付き合いいただきありがとうございました。

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes