Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
31
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

Pythonでシェルコマンドの実行結果をリストで渡す方法

はじめに

Pythonでシェルコマンドを扱いたい場合には、一般的にsubprocessモジュールを使う。モジュール内のstdout.readlines()を使うとリストとして結果を渡すことが可能であるが、実行するシェルコマンドが複数行に渡る場合、改行コード(ラインフィード)が一緒に渡ってしまう。そこで改行コード(ラインフィード)を取り除いた状態でリストを渡すには以下のように処理すればよい。

ここではシェルコマンドとして、ls -lをPythonから実行する例を使って解説する。

今回、以下の3通りに沿って3つスクリプトを作成した。

  • シェルの実行結果と同じものを取得する場合(res_cmd.py)
  • ラインフィードありのリストを取得する場合(res_cmd_lfeed.py)
  • ラインフィードなしのリストを取得する場合(res_cmd_no_lfeed.py)

実際に、ls -lを実行した場合の結果サンプルは以下の通りであるとする。

$ ls -l
total 12
-rwxr-xr-x 1 root root 260 Jun 16 18:48 res_cmd_lfeed.py
-rwxr-xr-x 1 root root 378 Jun 16 18:49 res_cmd_no_lfeed.py
-rwxr-xr-x 1 root root 247 Jun 16 18:48 res_cmd.py

シェルの実行結果と同じものを取得する場合

communicate()の1つ目の配列要素を取得すれば良い。

res_cmd.py
#!/usr/bin/python

import subprocess

def res_cmd(cmd):
  return subprocess.Popen(
      cmd, stdout=subprocess.PIPE,
      shell=True).communicate()[0]

def main():
  cmd = ("ls -l")
  print(res_cmd(cmd))

if __name__ == '__main__':
  main()

以下の通り、スクリプトの実行結果はls -lを実行した場合と同じである。

$ ./res_cmd.py
total 12
-rwxr-xr-x 1 root root 260 Jun 16 18:48 res_cmd_lfeed.py
-rwxr-xr-x 1 root root 378 Jun 16 18:49 res_cmd_no_lfeed.py
-rwxr-xr-x 1 root root 247 Jun 16 18:48 res_cmd.py

ラインフィードありのリストを取得する場合

stdout.readlines()を使う。

res_cmd_lfeed.py
#!/usr/bin/python

import subprocess

def res_cmd_lfeed(cmd):
  return subprocess.Popen(
      cmd, stdout=subprocess.PIPE,
      shell=True).stdout.readlines()

def main():
  cmd = ("ls -l")
  print(res_cmd_lfeed(cmd))

if __name__ == '__main__':
  main()

ラインフィードが含まれた結果のリストが取得できる。

$ ./res_cmd_lfeed.py
['total 12\n', '-rwxr-xr-x 1 root root 261 Jun 16 18:52 res_cmd_lfeed.py\n', '-rwxr-xr-x 1 root root 380 Jun 16 18:52 res_cmd_no_lfeed.py\n', '-rwxr-xr-x 1 root root 248 Jun 16 18:51 res_cmd.py\n']

ラインフィードなしのリストを取得する場合

stdout.readlines()を使い、かつ、リスト内包表記でrstrip("\n")を使う。

res_cmd_no_lfeed.py
#!/usr/bin/python

import subprocess

def res_cmd_lfeed(cmd):
  return subprocess.Popen(
      cmd, stdout=subprocess.PIPE,
      shell=True).stdout.readlines()

def res_cmd_no_lfeed(cmd):
  return [str(x).rstrip("\n") for x in res_cmd_lfeed(cmd)]

def main():
  cmd = ("ls -l")
  print(res_cmd_no_lfeed(cmd))

if __name__ == '__main__':
  main()

ラインフィードを除いた結果のリストが取得できる。

$ ./res_cmd_no_lfeed.py
['total 12', '-rwxr-xr-x 1 root root 261 Jun 16 18:52 res_cmd_lfeed.py', '-rwxr-xr-x 1 root root 380 Jun 16 18:52 res_cmd_no_lfeed.py', '-rwxr-xr-x 1 root root 248 Jun 16 18:51 res_cmd.py']
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
31
Help us understand the problem. What are the problem?