本シリーズのトップページ |
---|
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
001.py
上述のシェルスクリプトを、Python パッケージ「sh」を使って "真面目に" 置き換えた版である.
この実装方法だと「sh」の使用方法を調べつつになるので、
subprocess からの置き換えるメリットはほとんどないと思う.
コード
冗長かも知れないが、シェルでの実行した場合をコメントとして記している.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sh
if __name__ == '__main__':
# 「buf=03310e2f-f61f-494c-9eb8-dfe4d26660f4」となる
buf = sh.uuidgen().rstrip()
# 「echo $buf | sed "s/$buf/-/g"」により「UUID=03310e2ff61f494c9eb8dfe4d26660f4」を得る
UUID = sh.sed(sh.echo(buf), 's/-//g').rstrip()
# TMPDIR=/tmp/03310e2ff61f494c9eb8dfe4d26660f4
TMPDIR = f'/tmp/{UUID}'
# mkdir -p /tmp/03310e2ff61f494c9eb8dfe4d26660f4
sh.mkdir('-p', TMPDIR)
# cd /tmp/03310e2ff61f494c9eb8dfe4d26660f4
sh.cd(f'/tmp/{UUID}')
# 追記モードでファイル「/tmp/03310e2ff61f494c9eb8dfe4d26660f4/log」を作成する
FN = open(f'/tmp/{UUID}/log', 'a')
# pwd >> /tmp/03310e2ff61f494c9eb8dfe4d26660f4/log
sh.pwd(_out=FN)
# date "+%Y/%m/%d %H:%M:%S.%6N" >> /tmp/03310e2ff61f494c9eb8dfe4d26660f4/log
sh.date('+%Y/%m/%d %H:%M:%S.%6N', _out=FN).rstrip()
# echo '/tmp/03310e2ff61f494c9eb8dfe4d26660f4/log に書き込みました'
print(sh.echo(f'{FN.name} に書き込みました').rstrip())
# cat -n /tmp/03310e2ff61f494c9eb8dfe4d26660f4/log
for l in sh.cat('-n', f'/tmp/{UUID}/log'):
print(l.rstrip())
実行結果
/tmp/f7d811e7d8b042baa0dac5fc38db3a1b/log に書き込みました
1 /tmp/f7d811e7d8b042baa0dac5fc38db3a1b
2 2021/08/04 20:21:55.891392
参考情報
項目 | 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"
以上