カテゴリー
【シェルスクリプトツール作成の基本】引数指定で動作するシェルスクリプトを自作する
※ 当ページには【広告/PR】を含む場合があります。
2021/03/28
はじめに
引数を順番に呼び出すスクリプト
#!/bin/bash
noarg_err() {
echo "ERROR: must provide both of arg1 and arg2!" 1>&2
exit 1
}
noinputfile_err() {
echo "ERROR: not allowed an input file to be empty!" 1>&2
exit 1
}
if [ -z "$1" ] || [ -z "$2" ]; then
noarg_err
fi
if [ -z "$3" ]; then
noinputfile_err
fi
#👇実行したプログラム名(相対フォルダパス付き)
echo "PROGRAM: $0"
#👇実行したプログラム名(プログラム名のみ)
echo "PROGRAM: $(basename $0)"
#👇引数部分の表示
echo "$@"
echo "$*"
#👇引数の数(スペース文字切り)
echo "$#"
#👇引数の個別の読み出し
echo "FILE: $3, ARG1: $1, ARG2: $2"
$ chmod +x my_simple_script.sh
$ ./my_simple_script.sh piyo fuga hoge.csv
./1.sh piyo fuga hoge.csv
PROGRAM: ./my_simple_script.sh
PROGRAM: my_simple_script.sh
piyo fuga hoge.csv
piyo fuga hoge.csv
3
FILE: hoge.csv, ARG1: piyo, ARG2: fuga
記号 | 機能 |
---|---|
$@もしくは$* | コマンド以降に指定された引数部分を表示 |
$# | 空白文字切りされた位置で引数の数をカウント |
$? | シェルが最後に実行したコマンドの終了状態を保持 |
$$ | 現在のシェルのプロセス番号を保持 |
$- | シェルにセットされているオプションを保持 |
$0 | コマンドに指定された文字列をキャプチャ |
$! | 直前に実行されたバックグラウンドプロセスのプロセス番号を保持 |
$1 $2 $3 ... $9 | 各引数に指定された文字列を順番にキャプチャ |
setコマンド | シェルのオプションの設定/解除をおこなう。IFS(変数)で区切られたフィールドの取り出しと位置パラメータとして代入する |
shiftコマンド | 位置パラメータの内容を左に1つシフトする。($1は$2の内容、$2は$3の内容...と左に送られる)・$#の内容も送る度に1つ減少する |
$1 $2 $3 ...
getoptsを使って引数をオプションにしたスクリプト
getopts
使用したいオプション文字列
コマンドに指定されたオプション文字
-a hoge
a:
OPTARG
#!/bin/bash
usage_exit() {
echo "USAGE: $(basename $0) [-1 arg1] [-2 arg2] [-h help] [input_file]" 1>&2
exit 1
}
noarg_err() {
echo "ERROR: must provide both of arg1 and arg2!" 1>&2
exit 1
}
noinputfile_err() {
echo "ERROR: not allowed an input file to be empty!" 1>&2
exit 1
}
while getopts 1:2:h OPT; do
case $OPT in
1 ) ARG1="$OPTARG"
;;
2 ) ARG2="$OPTARG"
;;
h ) usage_exit
;;
\? ) usage_exit
;;
esac
done
#👇①不要となったオプション部分をshiftコマンドで切り捨て
shift $((OPTIND - 1))
if [ -z "$ARG1" ] || [ -z "$ARG2" ]; then
noarg_err
fi
if [ -z "$1" ]; then
noinputfile_err
fi
echo "FILE: $1, ARG1: ${ARG1}, ARG2: ${ARG2}"
$OPTIND
$1...
$ chmod +x my_interactive_script.sh
$ ./my_interactive_script.sh -h
USAGE: my_interactive_script.sh [-1 arg1] [-2 arg2] [-h help] [input_file]
$./my_interactive_script.sh -1 piyo -2 fuga hoge.csv
FILE: hoge.csv, ARG1: piyo, ARG2: fuga
-a hoge -b piyo -c
弱点① ~ ロングオプションが作れない
--version
--version
-v
-V
--verbose
--version
-v
弱点② ~ オプションを指定する順序に制限がある
$ ./hoge.sh -1 piyo -2 fuga -3 mofu awesome1.csv awesome2.csv
$ ./hoge.sh awesome1.csv -1 piyo -2 fuga awesome2.csv -3 mofu
引数の解析を自前でカスタマイズする方法
$@
#!/bin/bash
PROGNAME="$(basename $0)"
usage() {
cat << EOS >&2
Usage: ${PROGNAME} [--hoge] [-1, --fuga [VALUE]] [-2, --piyo VALUE]
A sample script of parsing on bash.
Options:
--hoge A single option.
--fuga A option with optional value.
--piyo A option with required value.
-h, --help Show usage.
EOS
exit 1
}
#👇オプションのパース結果の格納
PARAM=()
for opt in "$@"; do
case "${opt}" in
#👇ヘルプ表示は単独で利用
'-h' | '--help' )
usage
;;
#👇オプションに指定の値が無い場合
'--hoge' )
HOGE=true; shift
;;
#👇オプションに指定する値を任意にする場合
'-1' | '--fuga' )
FUGA=true; shift
if [[ -n "$1" ]] && [[ ! "$1" =~ ^-+ ]]; then
FUGA_VALUE="$1"; shift
fi
;;
#👇オプションに指定する値を必須にする場合
'-2' | '--piyo' )
if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
echo "${PROGNAME}: Option needs an argument -- $( echo $1 | sed 's/^-*//' )" 1>&2
exit 1
fi
PIYO=true; PIYO_VALUE="$2"; shift 2
;;
#👇オプションの終端を検出(このオプション以降に指定したオプションは値として解釈される)
'--' | '-' )
shift
PARAM+=( "$@" )
break
;;
#👇上記で定義した'-<文字>'以外のオプションは許容しない
-* )
echo "${PROGNAME}: Invalid option detected -- '$( echo $1 | sed 's/^-*//' )'" 1>&2
exit 1
;;
#👇'-'無しのオプションは値としてキャプチャされる
* )
if [[ -n "$1" ]] && [[ ! "$1" =~ ^-+ ]]; then
PARAM+=( "$1" ); shift
fi
;;
esac
done
#👇オプション無しの値を使う場合の処理
INPUT_FILE="${PARAM}"; PARAM=("${PARAM[@]:1}")
[[ -z "${INPUT_FILE}" ]] && usage
#👇無効なオプションがある場合にusageで抜ける
if [[ -n "${PARAM[@]}" ]]; then
usage
fi
#👇結果を出力
cat << EOS
HOGE > ${HOGE:-false} : FUGA > ${FUGA:-false} : PIYO > ${PIYO:-false}
FUGA_VALUE > ${FUGA_VALUE} : PIYO_VALUE > ${PIYO_VALUE}
INPUT_FILE < ${INPUT_FILE}
EOS
my_custom_script.sh
-h
--help
$ chmod +x my_custom_script.sh
$ ./my_interactive_script.sh -h
Usage: my_custom_script.sh [--hoge] [-1, --fuga [VALUE]] [-2, --piyo VALUE]
A sample script of parsing on bash.
Options:
--hoge A single option.
--fuga A option with optional value.
--piyo A option with required value.
-h, --help Show usage.
$ ./my_interactive_script.sh --help
#先ほどと同じ出力
$ ./my_custom_script.sh --hoge --fuga abc --piyo 123 awesome.csv
HOGE > true : FUGA > true : PIYO > true
FUGA_VALUE > abc : PIYO_VALUE > 123
INPUT_FILE < awesome.csv
$ ./my_custom_script.sh awesome.csv --hoge --fuga abc --piyo 123
HOGE > true : FUGA > true : PIYO > true
FUGA_VALUE > abc : PIYO_VALUE > 123
INPUT_FILE < awesome.csv
$ ./my_custom_script.sh awesome.csv -1 abc --piyo 123
HOGE > false : FUGA > true : PIYO > true
FUGA_VALUE > abc : PIYO_VALUE > 123
INPUT_FILE < awesome.csv
$ ./my_custom_script.sh --hoge awesome.csv -2 123
HOGE > true : FUGA > false : PIYO > true
FUGA_VALUE > : PIYO_VALUE > 123
INPUT_FILE < awesome.csv
$ ./my_custom_script.sh awesome.csv --piyo
my_custom_script.sh: Option needs an argument -- piyo
まとめ
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー