こんにちは。
シェルスクリプトの使用方法の記述からオプション解析コードを生成するという課題で、ChatGPT へ口頭試問を行う続編を行い1、概ね優れた回答をもらいました。
今回の回答ではオプション解析の while ループ部が簡素化な形となりました。使用方法の記述との対応性が良いので、コード生成を機械的に行えそうと思います(自作可能で、ChatGPT へ依頼しなくても良い)。
ChatGPT への質問
次の条件および使用方法の記述から、シェルスクリプトのオプション解析コードを作ってください。
- POSIX 準拠、かつ getopt や getopts は使用しない。
- while ループの中で case と shift を用いオプションを解析し、変数値を設定する。
- echo や exit などの動作はループ以降で行う。
- 引数付きオプションの解析処理は関数化し引数欠落の場合を判定する。
Name: $PROGNAME - parse arguments$LF
Usage: $PROGNAME [options] [__argument__...]$LF
Options:
-h|--help Print this usage and exit.
-d|--debug Set debug mode.
-n|--number __number__ Set non-negative integer (default: $number_var)
-m|--mammal __name__ Set mammal name.
ChatGPT からの回答
了解しました!
#!/bin/sh
# デフォルト値
number_var=0
mammal_var=""
debug_enabled=0
help_enabled=0
error_message=""
# メッセージ
PROGNAME=$(basename "$0")
WARNING="Warning: Type \"$PROGNAME --help\" for usage instructions."
USAGE="Usage: $PROGNAME [options] [arguments...]
Options:
-h, --help Print this usage and exit.
-d, --debug Set debug mode.
-n, --number NUM Set non-negative integer. (default: $number_var)
-m, --mammal NAME Set mammal name."
# オプションが引数を取る場合に正常な引数かを判定する関数
test_optarg() {
opt="$1"; var="$2"
case "$var" in -*|"")
error_message="Option '$opt' requires a proper argument."
return 1;;
esac
}
# オプション解析
while [ $# -gt 0 ]; do
opt="$1"
case "$opt" in
-h|--help)
help_enabled=1;;
-d|--debug)
debug_enabled=1;;
-n|--number)
shift; number_var="$1"
test_optarg "$opt" "$number_var" || break;;
-m|--mammal)
shift; mammal_var="$1"
test_optarg "$opt" "$mammal_var" || break;;
--) # オプション解析終了
shift; break;;
-*) # 不正なオプションに遭遇
error_message="Unknown option: $1"; break;;
*) # 通常の引数に遭遇したらオプション解析終了
break;;
esac
shift
done
# --- デバッグ出力 ---
if [ "$debug_enabled" -eq 1 ]; then
echo "Debug mode: $debug_enabled"
echo "Number: $number_var"
echo "Mammal: $mammal_var"
echo "Remaining arguments: $*"
fi
# --- エラー処理 ---
if [ -n "$error_message" ]; then
echo "$WARNING" >&2
echo "- $error_message" >&2
exit 1
fi
# --- ヘルプ表示 ---
if [ "$help_enabled" -eq 1 ]; then
echo "$USAGE"
exit 0
fi
# --- ここから通常の処理が続く ---
さらに
• -nオプションに対して「数値チェック」を追加したい
• オプションのまとめて解析(例えば -dn 5)も許したい
なども可能ですよ!