これは日々の作業を通して学んだことや毎日の生活で気づいたことをを記録しておく備忘録である。
HTML ファイル生成日時: 2024/12/21 11:44:57.596 (台灣標準時)
Bourne shell スクリプトにおけるコマンドライン引数の解析について調べて みたでござる。
まず、以下のようなものを書いてみたでござる。 $* を直接にいじってみたで ござる。
これを実行すると、以下のようになるでござる。#!/bin/sh # Time-stamp: <2022/04/17 14:17:06 (CST) daisuke> # function to print usage information print_usage () { echo "USAGE:" echo "" echo " test_args_00.sh -a AAA -b BBB -v file file file ..." echo "" } # making an empty variable for positional arguments args="" # command-line argument analysis while [ $1 ] do case $1 in -a) opt_a=$2 shift ;; -b) opt_b=$2 shift ;; -h) print_usage exit 1 ;; -v) opt_v=1 ;; -*) echo "invalid option!" echo "option $1 is not supported." print_usage exit 1 ;; *) args="$args $1" ;; esac shift done # optinal arguments echo "optional arguments:" echo " opt_a = $opt_a" echo " opt_b = $opt_b" echo " opt_v = $opt_v" # positional arguments echo "positional arguments:" for arg in $args do echo " $arg" done
-a や -b の値に空白を含む文字列を与えても問題ないでござる。% ./test_args_00.sh -a abc -b 123 -v foo bar baz optional arguments: opt_a = abc opt_b = 123 opt_v = 1 positional arguments: foo bar baz
上手くいっているように見えるのでござるが、 -a abc ではなく、 -aabc と 空白を入れずにオプションの値を指定すると問題が起きるでござる。% ./test_args_00.sh -a "abc def" -b 123 -v foo bar baz optional arguments: opt_a = abc def opt_b = 123 opt_v = 1 positional arguments: foo bar baz
% ./test_args_00.sh -aabc -b 123 -v foo bar baz invalid option! option -aabc is not supported. USAGE: test_args_00.sh -a AAA -b BBB -v file file file ...
次に、 getopt を使ったものを試してみたでござる。
これを実行してみると以下のようになるでござる。#!/bin/sh # Time-stamp: <2022/04/17 14:28:35 (CST) daisuke> # function to print usage information print_usage () { echo "USAGE:" echo "" echo " test_args_01.sh -a AAA -b BBB -v file file file ..." echo "" } # command-line argument analysis args=`getopt a:b:hv $*` || exit set -- $args while [ $1 ] do case "$1" in -a) opt_a=$2 shift shift continue ;; -b) opt_b=$2 shift shift continue ;; -v) opt_v=1 shift continue ;; -h) print_usage exit 1 ;; --) shift break ;; esac done # optinal arguments echo "optional arguments:" echo " opt_a = $opt_a" echo " opt_b = $opt_b" echo " opt_v = $opt_v" # positional arguments echo "positional arguments:" for arg in $* do echo " $arg" done
オプションの値を空白を入れずに指定しても問題ないのでござるが、 getopt だと空白を含む値を指定すると問題が起きるでござる。% ./test_args_01.sh -a abc -b 123 -v foo bar baz optional arguments: opt_a = abc opt_b = 123 opt_v = 1 positional arguments: foo bar baz % ./test_args_01.sh -aabc -b 123 -v foo bar baz optional arguments: opt_a = abc opt_b = 123 opt_v = 1 positional arguments: foo bar baz
% ./test_args_01.sh -a "abc def" -b 123 -v foo bar baz optional arguments: opt_a = abc opt_b = 123 opt_v = 1 positional arguments: def foo bar baz
最後に、 getopts を使ったコマンドライン引数解析を試してみたでござる。
実行すると、以下のようになるでござる。#!/bin/sh # Time-stamp: <2022/04/17 14:34:01 (CST) daisuke> # function to print usage information print_usage () { echo "USAGE:" echo "" echo " test_args_02.sh -a AAA -b BBB -v file file file ..." echo "" } # command-line argument analysis while getopts "a:b:hv" args do case "$args" in a) opt_a=$OPTARG ;; b) opt_b=$OPTARG ;; h) print_usage exit 1 ;; v) opt_v=1 ;; \?) print_usage exit 1 esac done shift $((OPTIND - 1)) # optinal arguments echo "optional arguments:" echo " opt_a = $opt_a" echo " opt_b = $opt_b" echo " opt_v = $opt_v" # positional arguments echo "positional arguments:" for arg in $* do echo " $arg" done
-a と abc の間に空白があってもなくても上手くいき、 また、 "abc def" というような空白を含む文字列をオプションの値 として与えても問題ないでござる。どうやら、 getopts を使うとよいようでご ざる。% ./test_args_02.sh -a abc -b 123 -v foo bar baz optional arguments: opt_a = abc opt_b = 123 opt_v = 1 positional arguments: foo bar baz % ./test_args_02.sh -aabc -b 123 -v foo bar baz optional arguments: opt_a = abc opt_b = 123 opt_v = 1 positional arguments: foo bar baz % ./test_args_02.sh -a "abc def" -b 123 -v foo bar baz optional arguments: opt_a = abc def opt_b = 123 opt_v = 1 positional arguments: foo bar baz
getopts の使い方は "man sh" を実行すれば読むことができるでござ る。
% man sh