前掲の記事でPythonとシェルスクリプトを合体させて1ファイル Python スクリプトを作ってみた。
で、実際にPythonの長めのコードを書いて、数日かけて実装・保守していて気づいたこと。
ファイルの先頭にシェルスクリプトあるの邪魔くせぇw
シェルスクリプト部分は基本固定でメインの編集対象はPython部分なんだけど、そのPython部分の開始位置が下の方にあるから始動が地味にめんどくさい。
なので、Pythonが先、シェルスクリプトが後になるように転置してみた。
#!/bin/sh
X=r'''';: "$X" <<'##_THE_END_OF_PYTHON_CODE_##' '---------------------------'''
#
# Python Script from here
#
print('Hello world')
r'''---------------------------------------------------------------------------
##_THE_END_OF_PYTHON_CODE_##
#
# Shell Script from here
#
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SCRIPT_PATH="$SCRIPT_DIR/$(basename "$0")"
VENV_PATH="$SCRIPT_DIR/.$(basename "$0").venv"
# Python仮想環境を作成・実行
if [ -f "$VENV_PATH/bin/activate" ]; then
VENV_STATUS=exist
else
python3 -m venv "$VENV_PATH"
VENV_STATUS=new
fi
. "$VENV_PATH/bin/activate"
# 仮想環境を新規に作成した場合はpipを最新化
if [ $VENV_STATUS = new ]; then
pip install -q --upgrade pip
fi
# その他の必要なパッケージをインストール
sed -n 's/^# REQUIREMENTS.TXT:\(.*\)/\1/p' "$SCRIPT_PATH" \
>"$VENV_PATH/requirements.txt"
pip install -qr "$VENV_PATH/requirements.txt"
# Pythonスクリプトを実行
python3 "$SCRIPT_PATH" "$@"
# --------------------------------------------------------------------------'''
# requirements.txt from here
# REQUIREMENTS.TXT:Jinja2==3.1.6
# REQUIREMENTS.TXT:MarkupSafe==3.0.3
以下解説。特に読まなくてもいいかと。
例によって領域前後におまじないがある。
X=r'''';: "$X" <<'##_THE_END_OF_PYTHON_CODE_##' '---------------------------'''
これは、Python的には変数Xを単なる生文字列で初期化している。
X=r'''';: "$X" <<'##_THE_END_OF_PYTHON_CODE_##' '---------------------------'''
シェルスクリプト的には、シェル変数Xにrと空文字列''と空文字列''を連結した文字列rを代入し、同じ行で : コマンドを呼び出している。
: コマンドの最初のオプションは $X で、未使用警告を消す。
第2オプションはヒアドキュメントになっていて、Python部分のコード全体がはいる。
第3オプションはスペーサーというかパディングというか、79桁目まで伸ばして「Python部分の始まり」のボーダーにしている。
その後Python部分が始まり、次のボーダー
r'''---------------------------------------------------------------------------
##_THE_END_OF_PYTHON_CODE_##
まで続く。
r'''--- ... 以降はPython的にコメントというかただの生文字列で、シェルスクリプトのコードが始まる。
シェルスクリプト的には ##_THE_END_OF_PYTHON_CODE_## までが冒頭の : に渡される入力で、それ以降が実行対象となる。
# --------------------------------------------------------------------------'''
これが、シェルスクリプト的には#で始まるただのコメント、Python的には文字列の終端 '''。
その後ろには必要なモジュールを書いておいて、シェルスクリプト部分で仮想環境にインストールしている。
# requirements.txt from here
# REQUIREMENTS.TXT:Jinja2==3.1.6
# REQUIREMENTS.TXT:MarkupSafe==3.0.3
いじょ。