LoginSignup
3
1

More than 5 years have passed since last update.

Python上でShellに対してコマンド打ちながら結果をStringで拾う方法(パイプ対応付き)

Last updated at Posted at 2017-10-25

とりあえずソースコードはこちら

こいつらを使えばすべてString型でReturnされます。
ワイルドカード、>とかのタイプのパイプには未対応です。

ConsoleInput.py
# -*- coding: utf-8 -*-

#マルチパイプ処理もできるPythonコード。

import subprocess as sb
import sys

def S_InputConsole(CommandString):
    #コマンドを受け付けて、結果をStringで変換するコード

    #print("console In:" + CommandString)
    return sb.check_output(CommandString.split(" ")).decode("utf-8")


def InputPIPECommand(CommandString):

    #print("Console Pipe In: "+CommandString)
    #shell = TrueとなってるときはStringで打ち込んでもちゃんと読んでくれる。
    #shell = Trueとなっているときは、Shellに直打ちしているので、意図しないコードが発動した際は責任を持てません。
    #こいつにはワイルドカード,>,<,$(), 1>&2などすべての機能を使用可能
    #Tensorflowなど重い処理で結果をリアルタイムで出力してほしいときは、1>&2する。
    _execProcess = sb.Popen(
            CommandString,
            shell = True,
            stdin = sb.PIPE,
            stdout = sb.PIPE,
            stderr = sb.PIPE,
            ).communicate()[0]

    return _execProcess.decode("utf-8")

def S_InputPIPECommand(CommandString):
    #単一のパイプのみに対応する方法
    CommandList = CommandString.split("|")

    Exec1 = sb.Popen(CommandList[0].split(" "),stdout = sb.PIPE)
    Exec2 = sb.check_output(CommandList[1].split(" "),stdin = Exec1.stdout)

    return Exec2.decode("utf-8")

def S_InputMultiPIPECommand(CommandString):
    #1個以上のパイプに対応
    CommandList = CommandString.split("|")
    ExecNum=len(CommandList)
    CommandExecList =  []
    Execfirst = sb.Popen(CommandList[0].split(" "),stdout = sb.PIPE)
    CommandExecList.append(Execfirst)
    for CommandIndex in range(1,ExecNum-1):
        ExecProgress = sb.Popen(CommandList[CommandIndex].split(" "),stdin = CommandExecList[CommandIndex-1].stdout,stdout = sb.PIPE)
        CommandExecList.append(ExecProgress)

    ExecLast = sb.check_output(CommandList[ExecNum-1].split(" "),stdin = CommandExecList[ExecNum-2].stdout)

    return ExecLast.decode("utf-8")



S_InputMultiPIPECommandの方は、自動でパイプ数を計測して、自動でつなげてくれます。まぁまぁ便利。

使用例

getlist.py

jpglist=S_InputMultiPIPECommand('cat ./hogeimagelist.csv | grep .*JPG').split('\n')
#jpglistが欲しいときに。

jpglatestlist = S_InputMultiPIPECommand('cat ./hoge.csv | grep .*JPG | grep 2017-10-\d\d').split('\n')
#最近のJPGlistが欲しいときに。

Totalfilelist = S_InputConsole('ls -R /dataset/').split('\n\n')
for filelist in Totalfilelist:
    Directory = filelist.split(':')[0]
    for _file in filelist.split(':')[1].split('\n'):
        if re.compile(r'JP\w*G').findall(S_InputMultiPIPECommand('identify '+Directory+_file+' | grep Format.*\n')) != []:
            S_InputConsole('mv '+Directory+_file+' '+Directory+_file[:-4]+'.JPG')  
#GIF画像と名乗っている癖に実はJPGというのを炙り出すコード(イメージとしてテキトーに書いてるのであてにして使わないこと。)

どれもShellScriptで書けばいいんじゃね?って思う人も居るだろうが、
複雑なコードはPythonだと開発スピードがえらく速い上、rm -rしたいときにチェックできたり、安全装置を挟んだりできるので、慣れてない人にうってつけ。
他にも何かと使えたりする。例外処理もできるし。

結果はどうでもいいからリアルタイムで標準出力を出してほしいときは、shell=True設定で末尾に1>&2をつけてエラー出力すると端末でも見れます。

以後、使い回してお使いください。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1