これは古い引用ですが、Perlの発明者であるLarryWallのこの原則は今でも有効だと思います。
「怠惰なプログラマーは、自分の仕事を成し遂げるためにできることは何でも再利用します。この美徳は、コードを一度だけ書くことを奨励することによって、コードの再利用につながります。」
— Larry Wall、「プログラマーの3つの美徳」
同じコマンドシーケンスを入力するのに飽きて、最後に、より少ないキーストロークで物事を実行するための優れたシェルスクリプトを作成するとします。ただし、異なる引数を使用して実行したい場合があり、間違いなく すばらしいスクリプトを複製したくない。コマンドラインから引数を指定して使用する方法が必要です。この記事はまさにそれをカバーしています。
スクリプト入力の処理
シェルスクリプトは、環境からいくつかの「魔法の」変数にアクセスできます。
-
$0
-スクリプトの名前 -
$1
-スクリプトに送信される最初の引数 -
$2
-スクリプトに送信される2番目の引数 -
$3
-3番目の引数...など -
$#
-提供された引数の数 -
$@
-提供されたすべての引数のリスト
#!/bin/bash
if [ $# -eq 0 ];
then
echo "$0: Missing arguments"
exit 1
elif [ $# -gt 2 ];
then
echo "$0: Too many arguments: $@"
exit 1
else
echo "We got some argument(s)"
echo "==========================="
echo "Number of arguments.: $#"
echo "List of arguments...: $@"
echo "Arg #1..............: $1"
echo "Arg #2..............: $2"
echo "==========================="
fi
echo "And then we do something with $1 $2"
引数のさまざまな組み合わせでこれを実行するいくつかの例を次に示します。
$ ./ex01.sh
./ex01.sh: Missing arguments
$ ./ex01.sh aa
We got some argument(s)
===========================
Number of arguments.: 1
List of arguments...: aa
Arg #1..............: aa
Arg #2..............:
===========================
And then we do something with aa
$ ./ex01.sh aa bb
We got some argument(s)
===========================
Number of arguments.: 2
List of arguments...: aa bb
Arg #1..............: aa
Arg #2..............: bb
===========================
And then we do something with aa bb
$ ./ex01.sh aa bb cc
./ex01.sh: Too many arguments: aa bb cc
1つまたは2つの引数がある場合、これは問題ありません。ただし、引数間のデフォルトの区切り文字はスペース文字であることに注意してください。また、スペースは引数のデフォルトの区切り文字であるため、興味深いことが起こる可能性があります。たとえば、これは、3つ以上の引数を持つ引用符を使用した場合に発生します。
$ ./ex01.sh aa "bb cc xx yy zz"
We got some argument(s)
===========================
Number of arguments.: 2
List of arguments...: aa bb cc xx yy zz
Arg #1..............: aa
Arg #2..............: bb cc xx yy zz
===========================
And then we do something with aa bb cc xx yy zz
スクリプトがbb cc xx yy zz
を解釈することに注意してください。 1つとして 値は二重引用符で囲まれているため、引数です。これが必要な場合も問題ありません。
[Linuxコマンドを手元に置いておきます。 AdvancedLinuxコマンドのチートシートをダウンロードします。 ]
もう1つの興味深い点は、スクリプトが変数から引数を取得するときです。 。変数にスペースが含まれている場合は、それが必要かどうかを判断する必要があります。 単一の引数として扱われる値、または異なる引数として扱われるすべての部分:
$ export AUTHOR="John Lennon"
$ export SONG="Imagine"
$ ./ex01.sh $AUTHOR $SONG
./ex01.sh: Too many arguments: John Lennon Imagine
$ ./ex01.sh "$AUTHOR" "$SONG"
We got some argument(s)
===========================
Number of arguments.: 2
List of arguments...: John Lennon Imagine
Arg #1..............: John Lennon
Arg #2..............: Imagine
===========================
And then we do something with John Lennon Imagine
引数を引用符で囲まれていない変数として送信すると、スクリプトはそれらすべてを個別の単語として解釈し、次の3つの引数を「認識」します。 John 、レノン 、および想像する 。
周りの引用符を使用する スクリプトが各変数を1つの引数として受け取るようにした変数は、この場合はより理にかなっています。
さらに多くの引数を処理する
ご覧のとおり、魔法の変数$@
スクリプトが受け取ったすべての引数のリストが含まれています。ループを使用して、すべての引数を処理できます。
#!/bin/bash
echo "We received $# argument(s)"
for i in "$@"
do
echo "Arg...: $i"
done
これはあなたにこれを与えます:
$ ./ex02.sh a b c e "stuff with spaces"
We received 5 argument(s)
Arg...: a
Arg...: b
Arg...: c
Arg...: e
Arg...: stuff with spaces
怠惰になることで賢くなる
シェルスクリプトで引数を処理する際に重要なことは、次のことを明確に理解することです。
- 議論の内容はどのような形をとる可能性がありますか?
- 変数として提供されている場合、「送信者」はその変数に何を入力しましたか?
- ユーザー入力によって提供される場合、ユーザーがロジックを「壊さない」ようにするにはどうすればよいですか?
- どの引数があなたのにとって受け入れ可能または必須であるか 脚本?
- 引数が無効な場合はどうしますか?スクリプトがエラーをスローしたり、デフォルト値を使用したりする可能性があります。
これが、スクリプトの一部を改善または再利用することによって、正しい方法で怠惰であり続けるのに役立つことを願っています。