Notebook

これは日々の作業を通して学んだことや毎日の生活で気づいたことをを記録しておく備忘録である。

HTML ファイル生成日時: 2024/12/21 11:44:57.596 (台灣標準時)

Bourne shell スクリプトにおけるコマンドライン引数の解析

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

これを実行すると、以下のようになるでござる。

% ./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 や -b の値に空白を含む文字列を与えても問題ないでござる。

% ./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

上手くいっているように見えるのでござるが、 -a abc ではなく、 -aabc と 空白を入れずにオプションの値を指定すると問題が起きるでござる。

% ./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 を使ったコマンドライン引数解析

次に、 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

これを実行してみると以下のようになるでござる。

% ./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

オプションの値を空白を入れずに指定しても問題ないのでござるが、 getopt だと空白を含む値を指定すると問題が起きるでござる。

% ./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 を使ったコマンドライン引数解析

最後に、 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

実行すると、以下のようになるでござる。

% ./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

-a と abc の間に空白があってもなくても上手くいき、 また、 "abc def" というような空白を含む文字列をオプションの値 として与えても問題ないでござる。どうやら、 getopts を使うとよいようでご ざる。

getopts の使い方

getopts の使い方は "man sh" を実行すれば読むことができるでござ る。


% man sh

fig_202204/man_sh_0.png
fig_202204/man_sh_1.png
fig_202204/sh_args_00.png
fig_202204/sh_args_01.png
fig_202204/sh_args_02.png
fig_202204/sh_args_03.png
fig_202204/sh_args_04.png
fig_202204/sh_args_05.png
fig_202204/sh_args_06.png
fig_202204/sh_args_07.png
fig_202204/sh_args_08.png


Frequently accessed files

  1. Computer___Python/20220518_0.html
  2. Computer___Network/20230726_00.html
  3. Misc___Taiwan/20240207_00.html
  4. Computer___Network/20230516_00.html
  5. Computer___FreeBSD/20220621_0.html
  6. Computer___Python/20220715_0.html
  7. Computer___Network/20230508_00.html
  8. Food___Taiwan/20220429_0.html
  9. Computer___Network/20240130_00.html
  10. Computer___NetBSD/20220817_3.html
  11. Computer___Python/20220410_0.html
  12. Computer___Network/20240416_00.html
  13. Computer___NetBSD/20230119_00.html
  14. Computer___Debian/20210223_1.html
  15. Computer___Python/20221013_0.html
  16. Computer___Python/20210124_0.html
  17. Computer___NetBSD/20220428_0.html
  18. Computer___NetBSD/20220818_1.html
  19. Computer___NetBSD/20240101_02.html
  20. Science___Math/20220420_0.html
  21. Computer___Python/20240101_00.html
  22. Computer___NetBSD/20220808_0.html
  23. Computer___TeX/20230503_00.html
  24. Science___Astronomy/20220503_0.html
  25. Computer___NetBSD/20230515_00.html
  26. Computer___Network/20220413_1.html
  27. Computer___NetBSD/20210127_0.html
  28. Computer___TeX/20231107_00.html
  29. Computer___Python/20220816_1.html
  30. Computer___Python/20230717_01.html


HTML file generated by Kinoshita Daisuke.