UNIX系OSのコマンドは引数としてオプションやパス名を指定できますが、シェルスクリプトでも同じように引数を指定できます。引数で指定した値はシェルスクリプト中では位置パラメータとして受け取ります。位置パラメータは前述した通り、0〜nの数字で表し、値を参照するときは前に$記号を付けます。
位置パラメータと関連する特殊パラメータには次のものがあります。
| 変数 | 内容 |
|---|---|
| $0 | 位置パラメータの最初のものですが引数の値ではなく、コマンド名または、シェルスクリプト名(パス名)を値として持っています。 |
| $# | 引数の数を値として持っています。 |
| $* | 全ての引数を空白で区切り、まとめて1つの変数とした値を持っています。 |
| $@ | 全ての引数を個別の値として持っています。 |
例1:位置パラメータの値を確認します。
$ set Param1 Param2 Param3 Param4 ← 位置パラメータ1から4に値を設定 $ echo $0 ← 位置パラメータ0の値を表示 /bin/bash ← コマンド名(bash)が設定されている $ echo $1 ← 位置パラメータ1の値を表示 Param1 $ echo $2 Param2 $ echo $3 Param3 $ echo $4 Param4 $ echo $# ← 値が設定されている位置パラメータの数を表示 4 $ echo $* Param1 Param2 Param3 Param4 ← 全ての位置パラメータの値 $ echo $@ Param1 Param2 Param3 Param4 ← 全ての位置パラメータの値 $ set "$*" ← set "$1 $2 $3 $4"と同じ $ echo $1 Param1 Param2 Param3 Param4 ← 位置パラメータ1に全ての位置パラメータの値が設定されている $ set Param1 Param2 Param3 Param4 $ set "$@" ← set "$1" "$2" "$3" "$4"と同じ $ echo $1 Param1 ← 位置パラメータ1には"$1"の値が設定されている $ echo $2 Param2 $
例2:引数で指定したディレクトリのバックアップを取ります。(ex20.sh)
$ ex20.sh $HOME/KANRI ← 引数を指定 ./ ./manpo.ksp ./kakei.ksp バックアップ完了 $
例3:ディレクトリ(位置パラメータ1)の指定が無かったらメッセージを出力して中止します。(ex21.sh)
$ ex21.sh ← ディレクトリの指定をしないで実行 バックアップするディレクトリの指定がありません。中止します。 ← エラーメッセージ $
シェルはユーザが入力した文字列を解釈して、さまざまなことを行っていますが、文字には特別な意味を持つ記号がいくつかあります。例えば、次のような記号が該当します。(全てではありません)
半角スペース タブ * ? [ ] > < ; | & $ { } ( ) #
これらの記号を単なる文字として扱いたい場合は特別な指定が必要です。例えば、「* Hello *」のメッセージを出力したい場合、単にecho * Hello *では期待した結果になりません。
$ echo * Hello * ex01.sh ex02.sh ex03.sh ex10.sh ex20.sh ex21.sh loop.c loop.prg Hello ex01.sh ex02.sh ex03.sh ex10.sh ex20.sh ex21.sh loop.c loop.prg $
単に「*」だけを指定したのでは、シェルは「*」を「任意の長さの任意の文字列」と解釈してしまいます。ここでは「*」を単なる文字として扱いたいので、その旨、シェルに伝える必要があります。このことをエスケープと呼んでおり、次のような、エスケープを表す記号があります。
"(引用符)'(アポストロフィ)\(バックスラッシュ)
先程の、echo * Hello *の場合であれば、引用符かアポストロフィで括ります。
$ echo '* Hello *' ← アポストロフィで括ってエスケープ * Hello * $
例1:アポストロフィと引用符の相違を確認します。
$ name=メリー
$
$ echo '*** 今日は${name}さん ***' ← アポストロフィで括る
*** 今日は${name}さん ***
$
$ echo "*** 今日は${name}さん ***" ← 引用符で括る
*** 今日はメリーさん ***
$
$ echo \* Hello \* ← *をバックスラッシュでエスケープ
* Hello *
$
例2:バックアップしたディレクトリのパス名を表示します。(ex30.sh)
$ ex30.sh ~/KANRI / ./manpo.ksp ./kakei.ksp *** /home/merry/KANRI以下のバックアップをとりました *** $
例3:コマンドを実行するときにもエスケープが必要な場合があります。
$ grep #! *.sh ← 拡張子が".sh"のファイルから、「#!」を含む行を表示する 使用法: grep [オプション]‥‥ 文字列パターン [ファイル]‥‥ ← grepの構文エラー 詳しくは`grep --help'を実行してください。 $ $ grep '#!' *.sh ← アポストロフィで括ってエスケープ ex01.sh:#!/bin/bash ex02.sh:#!/bin/bash ex03.sh:#!/bin/bash ex10.sh:#!/bin/bash ex20.sh:#!/bin/bash ex21.sh:#!/bin/bash ex30.sh:#!/bin/bash $ $ cd DOC $ ls My Documents Program Files $ $ cd My Documents ← My Documentsは半角スペースを含む bash: cd: My: そのようなファイルやディレクトリはありません $ cd 'My Documents' ← 半角スペースをエスケープするためにアポストロフィで括る $ ls work.ods 財産目録.ods 総勘定元帳.ods 合計残高資産表.ods 精算表.ods 貸借対照表.ods $