このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

Linuxコマンドの基本:シェルスクリプトの位置パラメータ

シェルスクリプトの位置パラメータ

 シェルスクリプトでは、コマンドライン引数を受け取って処理することができます。これにより、スクリプトの動作を実行時にカスタマイズしたり、動的に入力を受け取ることが可能になります。これらのコマンドライン引数を扱うために、位置パラメータと呼ばれるシェル変数を使用します。

位置パラメータとは

 位置パラメータは、シェルスクリプトが実行されたときに渡されたコマンドライン引数を格納する特殊な変数です。以下のように定義されています。

  • $0:シェルスクリプト自身の名前
  • $1$2$3、…:コマンドライン引数1番目、2番目、3番目、…に対応

例えば、以下のようにシェルスクリプトを実行した場合

$ ./script.sh arg1 arg2 arg3

各位置パラメータには次の値が格納されます。

  • $0./script.sh
  • $1arg1
  • $2arg2
  • $3arg3

位置パラメータの利用方法

 実際に位置パラメータを使用して、コマンドライン引数を表示するシェルスクリプトを作成してみましょう。

ステップ1:command.sh の作成

user01@ubuntu:~$ nano command.sh

command.sh の内容

#!/bin/bash

echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
echo "\$4 = $4"
echo "\$5 = $5"
echo "\$6 = $6"

解説

  • echo "\$0 = $0":\$0 と記述することで、$ をエスケープし、$0 と表示します。その後、$0 の値を表示します。
  • $1$6 についても同様に処理しています。

ステップ2:実行権限の付与

user01@ubuntu:~$ chmod +x command.sh

ステップ3:スクリプトの実行

user01@ubuntu:~$ ./command.sh arg1 arg2 arg3

出力結果

$0 = ./command.sh
$1 = arg1
$2 = arg2
$3 = arg3
$4 = 
$5 = 
$6 = 

解説

  • $0 にはスクリプト名 ./command.sh が格納されています。
  • $1$3 にはコマンドライン引数が順番に格納されています。
  • $4$6 は未定義のため、空の値が表示されています。

ワイルドカードによる引数の展開

 シェルスクリプトを実行する際に、ワイルドカード * を引数として使用すると、現在のディレクトリ内のファイル名が展開されて位置パラメータに渡されます。

例:ワイルドカードを使用したスクリプトの実行

ステップ1:現在のディレクトリの内容を確認

user01@ubuntu:~$ ls
bin         work          デスクトップ  ピクチャ
command.sh  ダウンロード  ドキュメント  ミュージック
snap        テンプレート  ビデオ        公開

ステップ2:スクリプトの実行

user01@ubuntu:~$ ./command.sh *

出力結果

$0 = ./command.sh
$1 = bin
$2 = command.sh
$3 = snap
$4 = work
$5 = ダウンロード
$6 = テンプレート

解説

  • * は現在のディレクトリ内の全てのファイル名に展開されます。
  • 展開されたファイル名が位置パラメータ $1 以降に順番に格納されます。

引数の個数を取得する

特殊変数 $# を使用すると、スクリプトに渡された引数の個数を取得できます。

スクリプトの修正

command.sh の末尾に以下の行を追加します。

echo "\$# = $#"

修正後の command.sh

#!/bin/bash

echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
echo "\$4 = $4"
echo "\$5 = $5"
echo "\$6 = $6"
echo "\$# = $#"

スクリプトの再実行

user01@ubuntu:~$ ./command.sh arg1 arg2 arg3

出力結果

$0 = ./command.sh
$1 = arg1
$2 = arg2
$3 = arg3
$4 = 
$5 = 
$6 = 
$# = 3

解説

  • $# には引数の個数 3 が格納されています。

引数全体の参照

引数全体を一度に参照したい場合、特殊変数 $*$@ を使用します。

  • $*:全ての引数を一つの文字列として参照します。
  • $@:全ての引数を個別の文字列として参照します。

例:引数全体を表示するスクリプト

ステップ1:args-disp.sh の作成

user01@ubuntu:~$ nano args-disp.sh

args-disp.sh の内容

#!/bin/bash

echo "\$@ = $@"
echo "\$* = $*"

ステップ2:実行権限の付与

user01@ubuntu:~$ chmod +x args-disp.sh

ステップ3:スクリプトの実行

user01@ubuntu:~$ ./args-disp.sh arg1 arg2 "arg 3"

出力結果

$@ = arg1 arg2 arg 3
$* = arg1 arg2 arg 3

解説

  • $@$* は、一見同じように見えますが、ダブルクォートで囲むと挙動が異なります。

ダブルクォートで囲んだ場合の違い

スクリプトの修正

args-disp.sh を以下のように修正します。

#!/bin/bash

echo "\"\$@\" = "$@""
echo "\"\$*\" = "$*""

スクリプトの再実行

user01@ubuntu:~$ ./args-disp.sh arg1 arg2 "arg 3"

出力結果

"$@" = arg1 arg2 arg 3
"$*" = arg1 arg2 arg 3

 しかし、この出力では違いが見えにくいので、各引数を個別に表示するようにスクリプトを変更します。

スクリプトの再修正

#!/bin/bash

echo "\"\$@\" ="
for arg in "$@"
do
  echo "[$arg]"
done

echo "\"\$*\" ="
for arg in "$*"
do
  echo "[$arg]"
done

スクリプトの再実行

user01@ubuntu:~$ ./args-disp.sh arg1 arg2 "arg 3"

出力結果

"$@" =
[arg1]
[arg2]
[arg 3]
"$*" =
[arg1 arg2 arg 3]

解説

  • "$@":各引数が独立して展開されます。
  • "$*":全ての引数が一つの文字列に連結されます。

ラッパースクリプトでの活用例

シェルスクリプトで引数をそのまま他のコマンドに渡す場合、"$@" を使用すると便利です。

例:ls コマンドを英語環境で実行するラッパースクリプト

ステップ1:wrapper-ls.sh の作成

user01@ubuntu:~$ nano wrapper-ls.sh

wrapper-ls.sh の内容

#!/bin/bash

export LANG=C
ls "$@"

ステップ2:実行権限の付与

user01@ubuntu:~$ chmod +x wrapper-ls.sh

ステップ3:ls --helpコマンドを実行

まず、普通にls --helpコマンドを実行します。

user01@ubuntu:~$ ls --help 
使用法: ls [オプション]... [ファイル]...
FILE (デフォルトは現在のディレクトリ) に関する情報を一覧表示します。
-cftuvSUX のいずれも指定されず、 --sort も指定されていない場合、
要素はアルファベット順でソートされます。
...(以下省略)...

日本語で表示されます。

ステップ4:スクリプトの実行

wrapper-ls.shを実行します。

user01@ubuntu:~$ ./wrapper-ls.sh --help

出力結果

Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
...(以下省略)...

英語で表示されます。

解説

  • export LANG=C:環境変数 LANGC(英語環境)に設定します。
  • ls "$@":スクリプトに渡された全ての引数を ls コマンドにそのまま渡します。
  • これにより、ls --help の出力が英語になります。

位置パラメータ関連の特殊変数まとめ

変数説明
$0スクリプト自身の名前
$1$Nコマンドライン引数(1番目からN番目まで)
$#コマンドライン引数の個数
$*全ての引数を一つの文字列として参照
$@全ての引数を個別の文字列として参照

不要なファイルの削除

作成したスクリプトが不要になった場合、以下のコマンドで削除できます。

user01@ubuntu:~$ rm command.sh args-disp.sh wrapper-ls.sh

まとめ

  • 位置パラメータを使用すると、シェルスクリプトでコマンドライン引数を扱うことができます。
  • $0:スクリプト自身の名前を参照します。
  • $1$2、…:コマンドライン引数を順番に参照します。
  • $#:引数の個数を取得します。
  • $*$@:全ての引数をまとめて参照しますが、ダブルクォートで囲むと挙動が異なります。
    "$*":全引数を一つの文字列として展開します。
    "$@":各引数を個別の文字列として展開します。
  • ラッパースクリプトを作成する際には、"$@" を使用して引数をそのまま他のコマンドに渡すことが推奨されます。

これらの知識を活用して、柔軟で機能的なシェルスクリプトを作成してみてください。