スポンサーリンク

シェルとは

シェルとは1つの実行プログラムであり、通常はログインシェルとして各ユーザがログインするたびに起動されて、そのプロセスはログアウトの際に消滅します。

ログインが行われるとホストは端末上に、例えば % という表示を行っていますが、これがシェル(Cシェル)が発している「プロンプト」(ユーザへのコマンドラインへの入力を促す記号です。

シェルには大きく分けて、コマンドインタープリタとしての役割と、プログラム言語としての役割があります。コマンドインタープリタとしてのシェルは、プロンプトを出して、ユーザの入力したコマンドラインを解釈して、プログラムを実行し、プログラムが終了したら再びプロンプトを出すということを司ります。 シェル以外の別のプログラムを起動するには、普通はシェルのプロンプトのもとでコマンドを入力して行います。

シェルの種類

元来、シェルは sh という1種類しか存在しませんでした。sh は必要最小限の機能した持たなかったため、様々な亜種が作られることとなりました。シェルの種類によって機能が若干異なります。また。同じ機能でもシェルの種類によって文法が異なることがあります。

シェルの種類により、シェルスクリプトの文法も若干異なります。ログインシェルとして対話的に処理するには様々なシェルが使われていますが、色々なシェルの中で共通項的な位置にあり、どのUNIXシステムにも必ずあるシェルであるため、シェルスクリプトはBourneシェル用に書くのが普通になっています(プログラムとしての互換性を保つため)。

Unixシェルの種類
種類 説明
sh 様々な亜種が誕生したため、現在はそれらと区別するためにBourneシェル(略してBシェル)と呼ばれている。現在ではログインシェルとして使われることはほとんどないが、シェルスクリプトを書くためによく使われている。
bash Bourne Againシェル(bash)はBourneシェルの上位互換シェルである。Bourneシェルの構文を引き継ぎつつ、Bourneシェルにはない便利な機能を備えている。
csh Cシェル(csh)はC言語に似た構文を持つシェルである。Bourneシェルにはない便利な機能を備えている。Bourneシェルとは互換性がなく、同じ機能でもその構文が異なる。
ksh Kornシェル(ksh)はBourneシェルの上位互換シェルであり、Kシェルとも呼ばれる。Bourneシェルの構文を引き継ぎつつ、Bourneシェルにはない便利な機能を備えている。
tcsh TCシェル(tcsh)はCシェルの上位互換シェルである。
zsh Zシェル(zsh)はシェルの中でもとくに多機能なシェルである。

ログイン

sh

Bourneシェルがログインシェルであった場合、以下のファイルが存在すれば、その中に記述されたコマンドが実行されます。

  1. /etc/profile
  2. ユーザーのホームディレクトリの .profile

通常 .profile ファイルには、端末の種類や環境を指定するコマンドが入っています。

bash

Bourne Again シェルがログインシェルであった場合、以下のファイルが存在すれば、その中に記述されたコマンドが実行されます。

  1. /etc/profile
  2. ユーザーのホームディレクトリの .bash_profile
  3. ユーザーのホームディレクトリの .bash_login
  4. ユーザーのホームディレクトリの .profile

Bourne Again シェルがログインシェルでない場合、ユーザーのホームディレクトリの .bashrc が実行されます。

csh

Cシェルが起動されたとき、ホームディレクトリに.cshrcというファイルが存在すれば、その中に記述されたコマンドが実行される。

また、Cシェルがログイン・シェルとして起動された場合、以下のファイルが存在すれば、その中に記述されたコマンドも実行される。

これらのファイルは次の順序で実行される。

  1. $HOME/.cshrc
  2. /etc/.login (ログイン・シェルの場合)
  3. $HOME/.login (ログイン・シェルの場合)

これらのファイルは読み取り可能である必要がある。また、$HOME/.login$HOME/.cshrcは当該ユーザーがその所有者であるか、または当該ユーザーのグループIDがそのグループIDと一致するかチェックし、一致したときにのみ実行される。

通常 .login ファイルには、端末の種類や環境を指定するコマンドが入っている。

もし、C シェルを `-' で始まる名前で起動すると、その シェル はログインシェルとして実行される。

X環境では、-lsオプションを付けて起動したxtermやktermはログイン・シェルとなるが、-lsオプションを付けないで起動したxtermやktermはログイン・シェルにはならない。

リダイレクト

コマンドには標準的な入力デバイスが1つ、標準的な出力デバイスが2つ(正常時の出力とエラー時の出力)あります。これらをそれぞれ標準入力標準出力標準エラーと呼びます。通常、標準入力はキーボードに、標準出力と標準エラーはディスプレイに割り当てられています。

標準入出力
種別 ファイル記述子 デバイス
標準入力 0 キーボード
標準出力 1 ディスプレイ
標準エラー 2 ディスプレイ

これらを通常のデバイスではなく、ファイル等に変更することをリダイレクトといいます。

sh, bash

<ファイル名

指定したファイルを標準入力(ファイル記述子0)として使用します。

>ファイル名

指定したファイルを標準出力(ファイル記述子1)として使用します。ファイルが存在しない場合は作成します。ファイルが存在していれば、ファイルの長さを 0 にします。

>>ファイル名

指定したファイルを標準出力として使用します。ファイルが存在する場合、(EOF までシークした後 ) そのファイルに出力を追加します。ファイルが存在しない場合は、ファイルを作成します。

<&ファイル記述子

指定したファイル記述子(0以上の整数)に対応するファイルを標準入力として使用します。

>&ファイル記述子

指定したファイル記述子に対応するファイルを標準出力として使用します。

<&-

標準入力をクローズします。

>&-

標準出力をクローズします。

上記のいずれかの前に数字が付く場合、その値が (デフォルトの 0 または 1 の代わりに) 該当ファイルに対応したファイル記述子となります。

command 2>&1

この例では、現在ファイル記述子 1 に関連しているファイルに、ファイル記述子 2 を関連付けます。

リダイレクションを指定する場合、記述する順序が重要になります。シェルは、リダイレクション記述を左から右へ評価します。

command 1>xxx 2>&1

上記の例では、まず xxx というファイルにファイル記述子 1 を関 連付けます。次に、ファイル記述子 1 に関連するファイル ( つま り xxx) に、ファイル記述子 2 を関連付けます。リダイレクションの向きが逆であれば、まずファイル記述子 2 を端末に関連付け (ファイルを記述子 1 が既に端末に関連付けられているとみなし) 、次にファイル記述子 1 をファイル xxx に関連付けます。

csh

< ファイル名
標準入力をァイルへリダイレクトします。
<<word
標準入力を word と一致する行まで読み取り、それらの行を一 時 ファイルに格納します。word がエスケープされるかクォートされていなければ、格納された行に対して、変数およびコマンド置換が行われます。そして、一時ファイルを標準入力としてパイプラインが起動されます。word は変 数、ファイル名、およびコマンド置換の対象にはなりません。また、各行はシェルによって置換が実行される前に word と比較されます。
> ファイル名
標準出力をファイルへリダイレクトします。ファイルが存在しなければ作成します。存在すれば上書きします。このとき、以前の内容は失われます。変数 noclobber が設定されていれば、既存のファイルを 破壊しません。この変数は、! 形式のいずれかが使用されていないかぎり、端末および /dev/null へのリダイレクションも防ぎます。
>! ファイル名
標準出力をファイルへリダイレクトします。ファイルが存在しなければ作成します。存在すれば上書きします。このとき、以前の内容は失われます。
>& ファイル名
標準出力および標準エラーの両方をファイルへリダイレクトします。ファイルが存在しなければ作成します。存在すれば上書きします。このとき、以前の内容は失われます。変数 noclobber が設定されていれば、既存のファイルを 破壊しません。この変数は、! 形式のいずれかが使用されていないかぎり、端末および /dev/null へのリダイレクションも防ぎます。
>&! ファイル名
標準出力および標準エラーの両方をファイルへリダイレクトします。ファイルが存在しなければ作成します。存在すれば上書きします。このとき、以前の内容は失われます。
>> ファイル名
標準出力をファイルへリダイレクトします。指定したファイルが既に存在していた場合、ファイルの最後に追加します。noclobber 変数が設定されていると、存在しないファイルに対してはエラーになります。
>>! ファイル名
標準出力をファイルへリダイレクトします。指定したファイルが既に存在していた場合、ファイルの最後に追加します。指定したファイルが存在しない場合、ファイルを作成します。
>>& ファイル名
標準出力および標準エラーの両方をファイルへリダイレクトします。指定したファイルが既に存在していた場合、ファイルの最後に追加します。noclobber 変数が設定されていると、存在しないファイルに対してはエラーになります。
>>&! ファイル名
標準出力および標準エラーの両方をファイルへリダイレクトします。指定したファイルが既に存在していた場合、ファイルの最後に追加します。指定したファイルが存在しない場合、ファイルを作成します。

特殊なデバイスとして、ヌルデバイス(/dev/null)を指定することもできます。出力先とした場合、何も出力しないのと同義になります。入力元とした場合、常に EOF が入力されます。

$ echo hello > /dev/null
$

標準出力をヌルデバイスにリダイレクトした場合、/dev/nullというファイルに出力するのではなく、どこにも出力しないことになります。

シェルのコマンド

Unixシェルのコマンド
コマンド 説明 sh bash csh
alias コマンドの別名を定義する。
case 条件によって実行する処理を分岐する。
for 処理を繰り返し実行する。
foreach 処理を繰り返し実行する。
goto 処理位置を移動する。
history コマンドの履歴を表示する。
if 条件によって実行する処理を分岐する。
set シェル変数を表示又は設定する。
switch 条件によって実行する処理を分岐する。
unalias aliasコマンドで定義したコマンドの別名を削除する。
until 処理を繰り返し実行する。
while 処理を繰り返し実行する。

組み込みコマンド

bash

bashの組み込みコマンド
コマンド 説明
bg 停止中のジョブをバックグラウンドで実行する。
bind キーバインドを設定する。
builtin シェル組み込みコマンドを実行する。
cd 現在の作業ディレクトリを変更する。
command 外部コマンドを実行する。
compgen 補完候補を作成する。
complete 入力補完を設定する。
continue 次の繰り返しに飛ぶ
declare 変数を定義する。
dirs ディレクトリスタックを表示する。
disown ジョブをデーモン化する。
echo 文字列を表示する。
enable 組み込みコマンドの無効と有効を切り替える。
eval 文字列を評価してコマンドを実行する。
exec 現在のプロセスのままコマンドを実行する。現在のプロセス(シェル)は終了する。
exit シェルを終了する。
export 環境変数を設定する。
fc コマンドの履歴を編集したり実行する。
fg 停止中又はバックグラウンドジョブをフォアグラウンドで実行する。
help 組み込みコマンドのヘルプを表示する。
jobs 実行中のジョブを表示する。
kill プロセスを強制的に終了させる。
let 数値演算を行う。
local ローカル変数を定義する。
logout シェルからログアウトする。
popd ディレクトリスタックから取り出して現在のディレクトリを移動する。
printf 書式を指定して表示する。
pushd ディレクトリスタックにディレクトリを追加する。
pwd 現在のディレクトリを表示する。
read 標準入力から1行読み込む。
readonly 変数を読み込み専用にする。
return シェル関数を終了する。
shift コマンドラインオプションをシフトする。
shopt シェルのオプション動作を制御する変数の値をトグルさせる。
source 実行コマンドをファイルから読み込んで実行する。
suspend シェルの実行をサスペンドする。
test 条件式を評価する。
times プロセスの時間を表示する。
trap シグナルを送出する。
type コマンドがどのように解釈されるかを表示する。
typeset declareと同じ
ulimit リソースリミットを設定する。
umask ファイル新規作成時のパーミッションを設定する。
unset 変数を削除する。
wait プロセスをwaitする。

環境変数

環境変数はシェル変数とほぼ同じです。シェル変数との違いは、起動したプロセス(子プロセス)に自動的に値がエクスポートされか否かです。 シェル変数はそのシェル固有の変数であり、シェルから起動したプロセスに変数は引き継がれません。 対して環境変数は、シェルから起動したプロセスに変数が引き継がれます。

sh, bash

Bourneシェルの場合、シェル変数をエクスポートすることで環境変数と扱います。

export [ 変数名 ... ]

指定された 変数名 群に対し、後で実行されるコマンドの環境へ自動的にエクスポートされるようにマークを付けます。 引数を省略すると、現在のシェル実行中にエクスポートのマークが付けられた変数名を一覧表示します。 親シェルからエクスポートされた変数名は、現在のシェル実行中に再びエクスポートされた場合にだけ一覧表示されます。 関数名はエクスポートされません。

変数をエクスポートする例を次に示します。

$ var1=exported var2=notexported
$ export var1
$ echo $var1
exported
$ echo $var2
notexported
$ sh
$ echo $var1
exported
$ echo $var2

$

次に挙げる環境変数はシェルが使用するもので、意味は既に定義済みです。

変数名 意味
HOME cdコマンドのデフォルト引数。通常はホームディレクトリです。
PATH コマンド用検索パス。
CDPATH cd コマンドの検索パス
MAIL このパラメタにメールファイルの名前がセットされていて、かつ MAILPATH パラメタが設定されていない場合、シェルは指定されたファイルにメールが到着するとユーザーに通知します。
PS1 1 次プロンプト文字列。
PS2 2 次プロンプト文字列。
SHELL シェルは、呼び出されると、このパラメタが示す名前が環境中に存在するかを確かめます。
LANG 国際化情報を指定するのに用いる文字列。ユーザーはこの情報を利用して、さまざまな国の慣習に従って作業を進めることができます。
LC_ALL 空文字列でない正当な値に設定されていれ ば、 LANG およびすべての LC_* 変数の値に代わって使用されます。
LC_COLLATE 使用する文字照合順序を指定します。
LC_CTYPE 文字分類、文字変換および複数バイト文字の幅を指定します。
LC_MESSAGES 使用するメッセージデータベースの言語を指定します。

bash

Bourne Againシェルで変数をエクスポートするには、シェル組み込みコマンドのexportを実行する。

export [[name[=word]] ...

変数に値を代入するのと、変数のエクスポートを同時に行うことができる。たとえば、

$ PATH=/usr/local/HULFT/bin:$PATH
$ export PATH

は、次のようにすることができる。

$ export PATH=/usr/local/HULFT/bin:$PATH

csh

すべての環境変数の値を表示するには、envコマンドを使用します。

env

C シェルは、起動したプロセスに自動的に値がエクスポートされる環境変数と、そうでないシェル変数を区別します。この点は Bourne シェルとは異なります。

setenv [ 変数名 [ ] ]

引数を指定しないと setenv はすべての環境変数を表示します。 変数名 だけを指定すると、setenv は環境変数に空の値 (NULL) を設定します。 変数名 の両方を指定すると、setenv は環境変数に で指定した値を設定します。

最もよく使用される環境変数 USER、TERM、および PATH は、自動的に csh 変数 user、term、および path から (へ) インポート (エクスポート) されます。 したがって、これらの変数に setenv を使用する必要はありません。さらにシェルは、csh 変数 cwd が変更されるたびに、その値を環境変数 PWD へ設定します。

unsetenv 変数名

環境から 変数名 が示す変数を削除します。 unset のようなパターンマッチングは行いません。

メタキャラクタの打ち消し(エスケープ文字)

次の文字はシェルに対しては特別な意味を持ちます。

$ ; & ( ) | ^ < > 復帰改行 空白文字 タブ

これらの文字をメタキャラクタと呼びます。メタキャラクタのうち、次の文字はクォートしない(後述の説明を参照)限りワード(単語)の終わりを表します。

; & ( ) | ^ < > 復帰改行 空白文字 タブ

次の例は、word1;word2 という文字列を画面に出力するのではなく、word1 という文字列を画面に表示した後、word2 というコマンドを実行する、という意味でシェルは解釈します。

$ echo word1;word2

メタキャラクタの特別な意味を打ち消して、通常の文字として扱うには、次に示す3種類の方法があります。

メタキャラクタの特別な意味を打ち消して、文字自身を表すことをクォートと言います。シェルは、特定の文字をクォートして、それらが特別の意味を持たないようにすることがあります。

sh, bash

単一の文字をクォートするのに用いる \ は、コマンド実行前にワードから取り除かれます。\ と復帰改行との組み合せは、コマンドとパラメタの置換前にワードから取り除かれます。

一対の単一引用符(')で囲まれたすべての文字(ただし単一引用符は除く)は、シェルによってクォートされます。円記号は、一対の単一引用符で囲まれていれば特殊な意味を持ちません。 単一引用符は、一対の二重引用符で囲めばクォートされますが ( 例 "'" ) 、一対の単一引用符で囲んでもクォートされません。

一対の二重引用符 ("") の中では、パラメタとコマンドの置換が実施され、シェルは、その結果をクォートして、ブランクの解釈とファイル名の生成が行われないようにします。 $* が一組の二重引用符で囲まれている場合、定位置パラメタは置換され、クォートされ、クォートされた空白で分けられます ("$1 $2 ...") 。 しかし $@ が一組の二重引用符で囲まれている場合は、定位置パラメタは置換され、クォートされ、クォートされていない空白 ("$1" "$2" ... ) で分けられます。 \ は \、`、"、$ といった文字をクォートします。 \ と復帰改行との組み合せは、コマンドとパラメタの置換前にワードから取り除かれます。 バックスラッシュが \、`、"、$、および復帰改行以外の文字の前に付く場合は、バックスラッシュ自体がシェルによってクォートされます。

csh

ドル通貨記号は変数名の始まりであることを表す特別な意味を持ちます。この特別な意味を打ち消して単なるドル通貨記号として扱うには、打ち消し文字(エスケープ文字)を使用します。

% echo $variable
variable: 未定義の変数
% echo \$variable
$variable

打ち消し文字には円記号、2重引用符、1重引用符の3種類あり、それぞれ働きが異なります。

打消文字 意味
\ この文字の後の1文字の特別な意味を打ち消します。
" 文字列単位で打ち消します。ただし、2重引用符(")や感嘆符(!)、ドル記号($)、1重引用符(')の特別な意味は打ち消しません。
' 文字列単位で打ち消します。ただし、ドル記号($)や単一重引用符(')、感嘆符(!)の特別な意味は打ち消しません。

次に、シェルスクリプトとその実行例を示します。

% set name=yajima
% echo "$name"
yajima
% echo '$name'
$name

プロンプト

bash

bashを対話的に実行しているとき、コマンドを読み取る用意ができたら、優先プロンプトPS1が表示される。コマンドを完了するために、さらに入力が必要な時は、2次プロンプトPS2が表示される。

別名

シェルの種類によっては、コマンドに別の名前をつけることができます。

bash

alias

別名を全て表示します。

alias 別名=値

別名を設定します。

unalias 別名 ...

別名を削除します。

unalias -a

全ての別名を削除します。

csh

C シェルが持っている別名のリストは、alias および unalias コマンドを使用してユーザーが作成、表示、および変更できます。シェルは、各コマンドの最初のワードが既存の別名に一致するかどうかをチェックします。一致すれば、そのワードを別名に置き換えて再度コマンド処理を実行します。履歴置換のメカニズムは、そのコマンドが前の入力行であったかのように行うことが可能です。これによって履歴置換は (定義中ではバックスラッシュでエスケープされる) 、別名が使用されているとき、実際のコマンド行引数で置き換えることができます。履歴置換が 1 度も呼ばれていなければ、引数は変更されません。

別名はネストできます。すなわち、別名の定義の中に別の別名を入れてもかまいません。ネストされた別名は履歴置換が実行される前に展開されます。

最初のワードを除いて、別名を自分自身の定義内、また定義が参照している他のいかなる別名内にも書いてはいけません。このようなループが見つかると、エラーメッセージが表示されます。

ファイル名の補完

シェルの種類によってはファイル名の補完ができます。 コマンドラインからファイル名を入力する際、先頭の何文字かを入力してから何らかのキーを押すと、シェルが作業用ディレクトリからその文字列を含むファイル名を検索して、残りの文字を埋めます。 コマンドラインからの操作ではファイル名を入力する機会が多いので、ファイル名の補完機能があると便利です。

sh

Bourneシェルにファイル名の補完機能はありません。

bash

bash では Esc キーを 2 回押すと、ファイル名が補完されます。 例えば、作業用ディレクトリに mytext というファイルがある場合、vi my と入力して Esc キーを押すと、my という文字列が自動的に mytext というファイル名に補完されます。

もし、同一の名前をもつファイルがあったら、補完可能な部分まで表示されるので、残りはキーボードから入力します。

csh

filec 変数を設定することによって、対話型Cシェルは、部分的に入力されたファイル名またはユーザー名を補完することができます。

set filec

csh では Esc キーを押すと、ファイル名が補完されます。シェルは作業用ディレクトリからその文字を含むファイル名を検索して、残りの文字を埋めます。 例えば、作業用ディレクトリに mytext というファイルがある場合、vi my と入力して Esc キーを押すと、my という文字列が自動的に mytext というファイル名に補完されます。

ファイル名を部分的に入力して EOF 文字 (通常は CTRL-D) を入力すると、シェルは一致するすべてのファイル名を一覧表示します。そして、入力された不完全なコマンド行の内容を表示して、再度プロンプトを表示します。

最後のワード (入力値の一部) がチルド(~)で始まる場合、 シェルは現在のディレクトリのファイル名ではなく、ユーザー名を補完しようとします。

展開

bash

カンマ区切りの文字列をブレースで囲んだものは、個々に展開される。

$ echo {a,b,c}
a b c
$ echo mari{na,ri}
marina mariri
$ echo /{s,}bin
/sbin /bin

下記はcopy /home/marina/file /home/marina/file.bakと展開される。

$ copy /home/marina/file{,.bak}

ジョブ制御

シェルにはジョブの中断や再開、フォアグラウンド、バックグラウンドの切り替えなどのジョブ制御機能があります。

コマンドを実行中に ^Z (Ctrl + Z) を押すと、コマンドの実行を一時停止することができます。コマンドを一時停止すると、プロンプトが表示されて、他のコマンドを実行することができます。

一時停止したコマンドにはジョブ番号が付けられます。ジョブ番号を表示するには、jobs というシェル・コマンドを使用します。

jobs

一時停止したコマンドの実行を再開するには、プロンプトから fg というシェル・コマンドを実行します。

fg [ % ジョブ番号 ... ]
% cat
hello
hello
^Z
停止 (利用者要求による)
% cat hello
hello
% fg
cat
world
world
%

シェルスクリプト

シェルのプログラミングはファイルからの入力で行います。コマンドラインからの入力と違い、いくつもの命令を一括して実行できるのが利点です。この、いくつものコマンドを手順に応じて編集したファイルをシェルスクリプトと言います。シェルは条件分岐や繰り返しといった制御命令を持っていますので、複雑な手順を持ったシェルスクリプトを作成することも可能です。

シェルスクリプトの文法は、コマンドラインからの入力のそれと基本的に同じです。大きな違いは、シェルスクリプトはまとめてテキストファイルとして記述し、実行することができるという点です。

カレンダーを表示するシェルスクリプトの例を次に示します。

echo "=== カレンダー =="
cal
echo "================="

シェルスクリプトを実行する方法は、次の2通りあります。

  1. 引数にシェルスクリプトのファイル名を指定してシェルを実行する
  2. シェルスクリプトのファイルに実行権を付与してシェルスクリプトを実行する

ファイル名を引数としてシェルを実行することで、シェルスクリプトを実行することができます。

% csh scriptfile

chmodコマンドでスクリプトファイルに実行権を与えることで、スクリプトファイルをコマンドラインから直接実行することができます。

$ chmod +x scriptfile
$ scriptfile

スクリプトファイルに実行権を与えてコマンドラインから直製実行した場合、スクリプトファイル内でシェルの種類を指定していなければ、Bourneシェルで実行されます。 シェルの種類を指定するには、スクリプトファイルの第1行目に #! に続いて、使用するシェルを絶対パスによる表現で指定します。 Cシェルの絶対パスによる表現が /bin/csh の場合、Cシェルでスクリプトを実行するには、スクリプトファイルの第1行目に次の記述を行います。

#!/bin/csh

コメント(注釈)をつけるには、シャープ記号を用います。シャープ記号から文末までの文字列はコメントと解釈され、実行には影響を及ぼしません。

echo "hello world" #コメント文

外部スクリプトファイルの読み込み

ピリオドに外部スクリプトファイルのパスを指定すると、そのスクリプトファイルを読み込んで実行する。

. path

引数(定位置パラメータ)

シェルスクリプトを実行する際、引数を渡すことができます。

sh ファイル名 [ 引数 ... ]

スクリプトファイルに実行権を与えた場合は、次のようになります。

ファイル名 [ 引数 ... ]

n番目の引数の値は、$n で表されます。たとえば、1番目の引数の値は $1 で参照することができます。 $0 はシェル・スクリプトのファイル名を表します。

sh, bash

引数の個数は、$# で表されます。

$ cat showpara
echo $# $0 $1 $2
$ sh showpara p1 p2
2 showpara p1 p2

csh

n番目の引数の値を $argv[n] で表すこともできます。ただし、n に 0 を指定することはできません。

引数の個数は、$#argv で表されます。

% cat showpara
echo $#argv $0 $1 $2
% csh showpara p1 p2
2 showpara p1 p2

スクリプトで実行するコマンドとその引数を表示する

スクリプト内で実行するコマンドを表示するには、次に示す2つの方法がある。

シェルの引数に -x オプションを指定する例を次に示す。

$ cat script
echo current working directory
pwd
$ sh script
current working directory
/home/nakajima
$ sh -x script
+ echo current working directory
current working directory
+ pwd
/home/nakajima

スクリプト内に set -x と記述する例を次に示す。

$ cat script
#!/bin/sh
set -x
echo current working directory
pwd
$ script
+ echo current working directory
current working directory
+ pwd
/home/nakajima

実行するコマンドとその引数を表示するのを止めるには、シェルスクリプトにset +xと記述する。

関数

sh, bash

いくつかのコマンドをまとめて関数にすることができます。主にシェルスクリプト内で使用します。

関数名 () { コマンド ... }

関数を呼び出すときには、関数名を記述します。

関数名

関数を使用したシェルスクリプトの例を次に示します。

#!/bin/sh

func1()
{
    echo 関数が呼ばれました。
}

func1

関数には引数を渡すこともできます。関数内で引数を参照するには、定位置パラメーター( $ + 数字 )を使用します。第1パラメーターが $1、第2パラメーターが $2 で参照できます。

#!/bin/sh

func2()
{
    echo 関数が呼ばれました。引数は $1 と $2 と $3 です。
}

func2 para1 para2 para3

多重分岐 (switch, case)

case または switch コマンドは、処理の流れ(フロー)を制御する構文です。変数の値によって、実行するアクションを変えることができます。

sh, bash

case 変数 in [ パターンのリスト ) コマンドリスト ;; ] ... esac

case コマンドは、変数 に一致する最初の パターンのリスト に対応した コマンドリスト を実行します。 パターンの形式は、ファイル名生成に使用される形式と同じです。 ただしスラッシュ、先行するドット、およびスラッシュ直後のドットは、明示的に一致しなくてもかまいません。

パターンのリストには、ひとつ以上の値を指定します。複数の値を列挙するには、パイプ記号(|)で区切ります。

変数の値がパターンのリストのいずれかに一致すると、対応するコマンドリストを実行します。コマンドリストには、0個以上のコマンドを指定します。複数のコマンドを列挙するには、セミコロン記号(;)または改行で区切ります。コマンドリストの終端は、;; で表します。

case "$0" in
-sh | -ksh | -jsh)
  echo "hello"
  ;;
esac
case $? in
0)
  echo "hello"
  ;;
1)
  echo "world"
  ;;
esac

csh

switch ( 変数 )
  case パターン1:
    コマンド1
    breaksw
  case パターン2:
    コマンド2
    breaksw
  default:
    コマンド3
    breaksw
endsw

変数がパターン1と一致すれば、コマンド1を実行します。変数がパターン2と一致すれば、コマンド2を実行します。すべてのパターンに一致しなかった場合、コマンド3を実行します。

パターンで指定できる文字
文字 意味
* 任意の文字列
? 任意の1文字
[] []の中で指定された文字の中の任意の1文字
switch ( $string ) then
  case [a]*:
    echo "OK"
    breaksw
  default:
    echo "NO"
    breaksw
endsw

反復 (while, until)

while または until コマンドは、処理の流れ(フロー)を制御する構文です。指定した条件を満たす間、特定のアクションを繰り返し実行させることができます。

sh

while コマンドリスト1 do コマンドリスト2 done
until コマンドリスト1 do コマンドリスト2 done

while コマンドは、while コマンドリスト1 を繰り返し実行し、コマンドリスト1 中の最後のコマンドの終了ステータスが 0 の場合、do コマンドリスト2 を実行します。それ以外の場合、ループは終了しま す。 do コマンドリスト2 中のコマンドを実行しない場合、while コマンドは 0 の終了ステータスを返します。 ループ終了条件の判定を逆にするには、while の代わりに until を使用します。

csh

while ( 条件式 )
 コマンドリスト
end

コマンドリストは、ひとつのコマンドか、複数のコマンド群です。複数のコマンドを記述するには、次に示す2通りの方法があります。

条件が満たされている(条件式が真)間、whileとendで挟まれたコマンドを反復して実行します。

#!/bin/csh
set c=60
while ( $c > 0 )
  echo $c
  sleep 1
  @ c--
end

goto

sh, bash

BourneシェルおよびBourne Againシェルにはgotoコマンドはありません。

csh

goto ラベル
  ...
ラベル:
  コマンド1

特定の処理までジャンプさせます。ジャンプ先にラベルを指定しておき、ジャンプさせる場所にてそのジャンプ先ラベルを指定します。

#!/bin/csh
echo message1
goto labal1
echo message2
label1:
echo message3

exit

exit はシェルを終了させるコマンドです。

exit [ 数値 ]

呼び出し元のシェルまたはシェルスクリプトを数値で指定した終了ステータスで終了させます。数値を省略すると、最後に実行されたコマンドの終了ステータスがシェルの終了ステータスになります。

shift

sh, bash

$n+1 ... から始まる一連の定位置パラメタを $1 ... に 再命名 (リネーム) します。nを省略すると、1 とみなされます。

shift [n]
$ cat example.sh
echo $1 $2 $3
shift 1
echo $1 $2
shift 1
echo $1
$ sh example.sh foo bar baz
foo bar baz
bar baz
baz
$

csh

shift 変数名

shift命令を使うと、配列の要素をずらす(シフト)ことができます。シフトすると、2番目の要素が1番目となり、3番目の要素が2番目・・・・・・と配列の要素がひとつづつずれます。1番目の要素の内容は無くなり、全体の要素数はひとつ減ります。

#!/bin/csh
set array = ( a b c d e )
echo "arayの内容は $array です。"
echo "arrayの要素数は $#array です。"
shift array
echo "arayの内容は $array です。"
echo "arrayの要素数は $#array です。"

eval

sh

式を評価したうえでシェルのコマンドとして実行する。

eval [ argument ... ]

次のシェルスクリプトを実行すると $var=/tmp がエラーとなり、変数tmp_dirが設定されない。

#!/bin/sh
var=tmp_dir
$var=/tmp
echo $var
$ eval1
eval1: tmp_dir=/tmp: 見つかりません。

$

evalを使うと、$var=/tmptmp_dir=/tmp と評価され、変数tmp_dirが設定されるようになる。

#!/bin/sh
var=tmp_dir
eval $var=/tmp
echo $var
$ eval2
/tmp
$
スポンサーリンク