0
1

More than 3 years have passed since last update.

[02] subprocessの代替パッケージ「sh」を使ってみる

Last updated at Posted at 2021-08-04
本シリーズのトップページ
https://qiita.com/robozushi10/items/fabde36bb9a312347bc7

はじめに

一般的に Python で Linux コマンドを使う場合は subprocess を使うこと多い.
が、標準パッケージでは無いものの subprocess の代替である「sh」(amoffat/sh) も便利である.1

個人的な考えではあるが、「sh2」は標準パッケージでは無いので、職場などで使い込むと
他者の迷惑になり兼ねない。しかし、適度に使う分には subprocess よりも速く実装できて
好都合なので書き残しておく.

本項では「手抜きをして『sh』を使う場合」を記す.

この実装方法であれば シェルスクリプトに近い感覚で実装できるので、
前項 とは異なり subprocess よりも速く実装できるのではないかと思う.

セットアップ

pip 等で sh をインストールする.
詳細は本項末尾の「参考情報」に記した.

使用例

下記シェルスクリプト「001.sh」相当を、パッケージ「sh」を使って Python で実装する

001.sh

処理概要

前項と同じ内容である. (詳細はクリックすること)

001.sh の処理内容は、次の 1〜5 の処理である.
しかし、個人的には Python の subprocess でこの処理を実装しようとすると相当辛い.

`
1. ディレクトリ /tmp/<一意な文字列>/ を作成する
2. ディレクトリ /tmp/<一意な文字列>/ に移動する
3. ファイル /tmp/<一意な文字列>/log を作成する
4. pwd と date の実行結果を /tmp/<一意な文字列>/log に追加書き込みする
5. ファイル /tmp/<一意な文字列>/log を表示する
\
`

コード

前項と同じ内容である.

#!/bin/bash
# 一意な値を生成して UUID に格納する
UUID=`uuidgen`
mkdir -p /tmp/$UUID
cd /tmp/$UUID
touch log
pwd  >> log
date +"%Y/%m/%d %H:%M:%S.%6N" >> log
echo "/tmp/$UUID/log に書き込みました"
cat -n /tmp/$UUID/log

実行結果

/tmp/a0db1349-a758-44c9-b017-2b90f184ba84/log に書き込みました
     1  /tmp/a0db1349-a758-44c9-b017-2b90f184ba84
     2  2021/08/04 20:44:44.374856

 

002.py

上述のシェルスクリプトを、Python パッケージ「sh」を使って 手抜き実装した版 である.

bash -c <コマンド>」を使用しているので楽な記述になっており、
subprocess から置き換えるメリットがあるかと思われる.

なお、cd については sh.cd(パス) を使用しないと移動できないので注意すること.
これは bash -c だと別プロセスとして実行されているためだと推測している.

コード

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sh

if __name__ == '__main__':

  buf = sh.bash('-c', 'uuidgen').rstrip()
  UUID = sh.bash('-c', f'echo {buf} | sed "s/-//g"').rstrip()
  TMPDIR = f'/tmp/{UUID}'
  sh.bash('-c', f'mkdir -p {TMPDIR}')
  sh.cd(f'/tmp/{UUID}')
  sh.bash('-c', f'touch /tmp/{UUID}/log')
  sh.bash('-c', f'pwd >> /tmp/{UUID}/log')
  sh.bash('-c', f'date +"+%Y/%m/%d %H:%M:%S.%6N" >> /tmp/{UUID}/log')
  print(sh.bash('-c', f'echo "/tmp/{UUID}/log に書き込みました"').rstrip())
  for l in sh.bash('-c', f'cat -n /tmp/{UUID}/log'):
    print(l.rstrip())


実行結果

/tmp/19d2b497d10243a6bd19bf8194b78764/log に書き込みました
     1  /tmp/19d2b497d10243a6bd19bf8194b78764
     2  +2021/08/04 22:13:39.062400

参考情報

項目 URL 一言
Pypi sh https://pypi.org/project/sh/
公式ドキュメント - トップページ https://amoffat.github.io/sh/
公式ドキュメント - API逆引き https://amoffat.github.io/sh/reference.html
チュートリアル https://amoffat.github.io/sh/tutorials ここで実現したい機能を検索しながら使うことが多い
もた日記 https://wonderwall.hatenablog.com/entry/2017/07/30/083000

検討環境

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"

 

以上


  1. 私は職場で別の方が使用していて知った 

  2. パッケージ名が「sh」だと検索し辛い.. 

0
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
0
1