はじめに
shellでファイルをパースするのは結構しんどい。
正規表現を使って頑張って書いてもいいが、たいていは時間が経つと内容を忘れてしまう。
pythonのモジュールの力を借りることで正規表現の苦労から抜け出せたケースがあった。
これはその時の記録。
環境
- OS
- CentOS 7.4
- bash
- GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
- Python
- Python 3.6.8
具体的にはどうすればよいのか
bashのヒアドキュメントを利用してpythonコマンドに対してpythonのコードを流し込む。
shellscript
python <<EOF
# pythonのコード
EOF
尚bashのヒアドキュメントについてはここでは書きません。
詳しく知りたい方はご自身でお調べください。
サンプル
以下はサンプル。
pythonのconfigparserモジュール使ってmysql用のconfファイルを解析してMySQLに接続するshell scriptになっています。
connect_mysql.sh
#!/usr/bin/env bash## Connect to MySQLdeclare-rCOLOR_RED="\e[33;41;1m"declare-rCOLOR_OFF="\e[m"declare-rDB_CONFIG_PATH='path/to/database.conf'# check file exists or notif[!-f"${DB_CONFIG_PATH}"];then
echo-e"${COLOR_RED}[error] \"${DB_CONFIG_PATH}\" does not exist.${COLOR_OFF}"exit 1
fi
declare-rSECTION=$1# check argumentif[-z"$SECTION"];then
echo-e"${COLOR_RED}[error] Please set section name as command argument.${COLOR_OFF}"exit 1
fi######################################## Parse DB config by python# Globals:# DB_CONFIG_PATH# SECTION# Arguments:# None# Returns:# None#######################################function parse_ini_file (){
python3 <<'EOF' - "${DB_CONFIG_PATH}" "${SECTION}"
import sys
import configparser
file_path = sys.argv[1]
section_name = sys.argv[2]
config = configparser.ConfigParser()
config.read(file_path)
try:
details = config[section_name]
except KeyError:
sys.exit(1)
db_option = \
'[client]\\nhost={host}\\nport={port}\\ndatabase={database}\\nuser={user}\\npassword={password}\\n'\
.format(\
host=details['host'],\
port=details['port'],\
database=details['database'],\
user=details['user'],\
password=details['password']\
)
sys.stdout.write(db_option)
sys.exit(0)
EOF
}db_option=$(parse_ini_file)if[$?-ne 0 ];then
echo-e"${COLOR_RED}[error] Section \"${SECTION}\" does not exist in config file.${COLOR_OFF}"exit 1
fi
mysql --defaults-extra-file=<(echo-e${db_option})下記の様にすればヒアドキュメントでもpython ファイル名 引数1 引数2のようなことができるらしい。
python3 <<'EOF' - "${DB_CONFIG_PATH}" "${SECTION}"
...
EOF
おわりに
どなたかのお役に立てば幸いです。