シェルプログラムの先頭には#!/bin/sh
を書きます。
シェルプログラムのファイルには実行権限(xフラグ)を与える。
#
はコメントとして扱われます。
また、上記の様にダブルクォーテーションで囲むと、 echoコマンドの引数として扱われるため、コメントとしては取り扱われません。
コマンドは改行することで1つのコマンドとして区切られます。
改行を無視する場合、は\
を利用する
\
の前にスペースをいくら入力しても、1つのスペースに置き換えられる点に注意が必要です。
ワイルドカード | 説明 |
---|---|
* | 文字列全部 |
? | 一文字 |
[...] | [ ]の中に含まれる文字のどれか1つ |
[!...] | [ ]に含まれない文字 |
例 | |
---|---|
*abc | 〜abcの様に、abcで終わるファイル。abc というファイル名でもOK |
*abc* | ファイルの中にabc が含まれる文字列。 |
[a-z]* | a からz までの文字のどれかで始まるファイル。 |
[-a-z]* | - かa からz で始まるどれかで始まるファイル |
a-zA-Z]* | アルファベットの大文字か小文字で始まるファイル |
*[0-9]* | ファイル名の中に数字が含まれるファイル |
[!0-9]* | 数字では始まらないファイル |
?? | 2文字のファイル |
??* | 2文字以上のファイル |
abc/* | abc というディレクトリ下の全ファイル |
.
で始まるファイルを隠しファイルといいます。
隠しファイルはワイルドカードを利用しても除外されます。
\
を使うワイルドカードカード等のシェルにとって特別な文字は、メタキャラクタと呼ぶ。
;
、&
、(
、)
、|
、~
、<
、>
、?
、*
、[
、
]
、$
、'
、"
、バッククォート
、{
、}
、改行
、タブ
、スペース
1文字をクォートするにはバックスラッシュを使います。
シングルクォートで囲まれた文字列はすべて普通の文字となる。
ダブルクォーテーションはほとんどすべての文字をエスケープしますが、
$
、バッククオート、\
という3つの特殊文字はエスケープしません。
$
を利用した場合に変数名で展開される$
の場合はエスケープされるコマンドの引数がシェルに解釈されないようにしたいときに利用する。
シェルがそれを解釈してもよいかどうかを考えて利用する。
囲んだ文字列の中で、変数の置き換えやコマンド置き換えした結果を使いたいときは、 ダブルクォートを使う。
シングルクォートはそのままの文字として使いたい場合です。
シングルクォートはダブルクォートをエスケープでき、
ダブルクォートはシングルクォートをエスケープします。
バックスラッシュをエスケープするには、 シングルクォートでもバックスラッシュでも可能です。
シングルクォートの中で変数を展開したい場合は、以下のように書く
バッククォートはその中に書かれたコマンドを実行し、その結果をその位置に書き込みます。
バッククォートをバックスラッシュでエスケープすることにより、 コマンド置き換えのネストも可能です。
最初にecho def
の部分が置き換えられ、その後echo "abc def ghi"
が実行されます。
以下が同じ意味のコマンドです。
コマンドは慣例として、正しく終了したときは0、失敗したときは、1が終了時にセットされ、 エクジットステータスと言う。
exit status | 実行結果 | 正誤 |
---|---|---|
0 | 成功 | true |
1 | 失敗 | false |
またexit statusはコマンドを実行した直後に$?
という変数に代入される。
コマンドは通常改行でコマンド行となりますが、その他にもコマンドの区切りとするものがあります。
これらをまとめてコマンドセパレータと呼びます。
コマンドセパレータ | 説明 |
---|---|
改行 | 1つのコマンドの区切り |
; | 1つのコマンドの区切り |
| | 出力された結果を次のコマンドの入力にする |
& | バックグラウンドで実行させる |
|| | OR制御演算子 |
&& | AND制御演算子 |
セミコロンでコマンドを区切ると、左から順に実行されます。
セミコロンを使うと、複数行にまたがる記述を1行にまとめることができます。
左から右に流していくという意味で、パイプライン処理といいます。
|
の右側で実行したコマンドの結果を、|
の右側のコマンドの入力として処理する働きがあります。
パイプライン上にあるコマンドはそれぞれ別のプロセスとして動作しています。
一番右に書かれたコマンドの終了コードが、そのパイプライン全体の終了コードとなります。
command1 | command2
を書き直すと、
comamnd1 > tmpfile; command2 < tmpfile
となります。
command1
の結果をtmpfile
に書き込み、その後tmpfile
をcommand2
の入力とします。
アンパサンド(&)をコマンドの後ろにつけると、そのコマンドはバックグラウンドで実行されます。
command1 || command2
command1はすぐに実行されますが、command2は実行結果が0でない(trueではない)場合に限って実行されます。
command1 && command2
command1の実行結果が0(true)の場合に右側のコマンドが実行されます。
丸括弧()
や中括弧{}
を使ってコマンドをグルーピングすることで、
複数のコマンドをあたかも一つのものであるかのように実行させることができます。
()
によるグルーピング丸括弧で囲まれたコマンドは現在の動作しているシェルとは別にサブシェルのもとで動作することになります。
今のシェルが新しくシェルを動作させ、その中で動作するものです。
今のシェル(親)はサブシェル(子)が終了するまで次の処理には移行できません。
丸括弧を使うのは、現行の状態を変えたくは無いが、変えた状態で何かをやらなくてはならないときです。
{}
によるグルーピング中括弧を使って
{ command1; command2; ....; }
の様に、グルーピングすることもできます。
中括弧で囲むと、現行のシェルの中で実行されます。
中括弧の前後にはスペースが必要です。
また、中括弧の中の最後のコマンドはセミコロンが必要です。
改行すればセミコロンやスペースが不要となります。
中括弧を使うのは、それぞれのコマンドの結果をひとまとめにしたいようなときです。
makeコマンドの出力結果の前に、その日の日付を挿入する例です。
中括弧はネストさせることもできますし、バックグラウンドで走らせることもできます。
バックグラウンドで走らせた場合は、サブシェルで実行されます。
command-listの結果が0の場合はthen、
そうでない場合は、elseのcommandが実行されます。
fiでif文を閉じます。
else文はなくてもかまいません。
ifと同じ行にthenを書くこともできます。
また、testコマンドは、鉤括弧で代用可能です。
条件を増やす場合は、elif
文を利用します。
word-list
の部分には、スペースで区切って並べます。
command-listの部分が0ではなくなった場合に処理を抜けます。
実行結果は以下となります。
コロン(:)で無限ループの設定を行い、 何らかの条件でループを抜けるというやり方もできます。
コロンは、何も処理せず、0を終了コードとして返すコマンドです。
stringのところにある値が、それぞれのpatternという条件に合うかどうか調べていき 条件があった場合にその後ろにあるcommand-listに並べられたコマンドが実行されます。
;;
と書いたところまでが処理の対象となります。
caseの終わりはesac
という文字です。
patternの条件を設定するときには、ワイルドカードが利用できます。
パイプを使って複数の条件を設定することも可能です。
testコマンドは、ある条件を判定し、その条件が正しい場合には真(0の値)を返し、 誤っている場合には偽(0以外の値)を返します。
改行コードではなくセミコロンを使う事によって、複数のコマンドを1行に書くことができます。
メリットとして、見やすくなるということもありますが、
コマンドによっては1行にまとめてやらないと期待通りに動作しないものもあります。 (リモートシェル、Makefile)