読者です 読者をやめる 読者になる 読者になる

余白の書きなぐり

aueweのブログ

シェルスクリプトからPython3に移行する人のために ~標準入出力・ファイル管理編~

Python シェルスクリプト

汚いシェルスクリプトを保守する作業に嫌気がさしてきたので、Python3に乗り換えた。 せっかくなので必要になった知識を整理しておく。 同じようにシェルスクリフトから乗り換える人の役に立つと思う。

とりあえず IO 関連とファイル名の操作が重要な気がしたので、そのへんから書き始める。

環境変数の取得

# Python
import os
home = os.environ.get('HOME', "")

カレントディレクトリのパスを取得

# Bash ... もともと $PWDに入っているが
current_path=`pwd`
# Python
import os
current_path = os.getcwd()

# スクリプトのあるディレクトリの絶対パスは
script_path = os.path.abspath(os.path.dirname(__file__))

ファイル名とディレクトリ名の結合

シェルスクリプトではファイルやディレクトリを文字列として扱い、 適当に切ったり貼ったりしていたけれど、 Pythonでは os.path.join を使って行儀よく扱う必要がある。

# Bash
tmp_dir="$HOME/tmp"
tmp_file="${tmp_dir}/tmp.txt"
# Python
import os
home = os.environ.get('HOME', "")
tmp_dir  = os.path.join( home , "tmp"   )
tmp_file = os.path.join( tmp_dir, "tmp.txt")

# 諸事情でパスの区切り文字を変更したくなったら
tmp_dir_unix = tmp_dir.replace(os.path.sep, '/')   # /path/to/tmp_dir
tmp_dir_win  = tmp_dir.replace(os.path.sep, '\\')  # path\to\tmpdir

ディレクトリの作成

「同名のディレクトリの存在を確認して、無ければ作成」という定形作業

# Bash
if [ ! -d ${tmp_dir} ] ;then
    mkdir ${tmp_dir}
fi
# Python

import os
if not os.path.exists(tmp_dir):
  os.makedirs(tmp_dir)  # 再帰的作成

ディレクトリの削除

いくつか方法があるけれど、一番強力なやつは

# Bash
rm -rf ${tmp_dir}
# Python
import shutil
shutil.rmtree(tmp_dir)

ファイルへの書きこみ

# Bash
echo "hoge\npiyo" > ${tmp_file}
#Python
import codecs
f_out = codecs.open(tmp_file, "w", "utf-8")
print("hoge\npiyo", file=f_out)
f_out.close()

ファイルの読みこみ

# Bash
cat ${tmp_file}
# Python
import codecs
f_in = codecs.open(tmp_file, "r", "utf-8")
for line in f_in.readlines():
  print(line)
f_in.close()

外部プログラムの実行とパイプ処理

# Bash
cat ${tmp_file} | wc -l
# Python
from subprocess import Popen, PIPE
cat = Popen(["cat", tmp_file],                   stdout=PIPE)
wc  = Popen(["wc" , "-l"]    , stdin=cat.stdout, stdout=PIPE)
output = wc.stdout
for line in output:
  print(line)