シェルとコマンドラインシェルとシェルスクリプトの違い
混乱するので用語の確認をしてみた。
違い
用語 | 意味 |
---|---|
シェル | コマンドラインインタプリタ。ユーザがOSを操作するためのインタフェース。 |
コマンドラインシェル | Unixシェルのこと。コマンドをパイプでつなげたジョブを記述する。俗にシェル芸、ワンライナーと呼ばれる。 |
シェルスクリプト | OSのシェルまたはコマンドラインインタプリタ向けに書かれたスクリプト言語である。 |
コマンドラインシェルとシェルスクリプトの違い
改行。コマンドラインシェルは1行にせねばならない。そのために{}
, ()
, ;
, &&
を使う。シェルスクリプトは文を改行で区切れる。
呼び方
「シェル」と言ったとき「シェル」か「コマンドラインシェル」か「シェルスクリプト」か不明瞭。会話では文脈で判断することになる。略すときの方針を以下に仮定してみた。
用語 | 略 |
---|---|
シェル | シェル |
コマンドラインシェル | シェル |
シェルスクリプト | スクリプト |
シェルとコマンドラインシェルの区別をつける場面は少ないと思われる。伝わらなかったら「インタフェース、インタプリタのほう」「コマンドラインシェルのほう、ターミナルに打つヤツ」と言って区別してはどうか。シェルスクリプトについては「ファイルに書くヤツ、シバンを書くヤツ」などと言えば伝わりそう。頭悪そう。
シェル芸とは
非公式な用語。日本固有と思われる。
マウスも使わず、ソースコードも残さず、GUIツールを立ち上げる間もなく、あらゆる調査・計算・テキスト処理をCLI端末へのコマンド入力一撃で終わらすこと。あるいはそのときのコマンド入力のこと。
コマンドラインシェルを使って何らかの意味ある仕事をさせること、だと思う。
例
コマンドラインシェル
たとえば以下のようなコード。
echo -e 'A\nB\nA\nC' | sort | uniq > distinct.txt
echo -e 'A\nB\nC' | grep 'B' > result.txt
\
を行末に付与すれば複数行に渡って表記できる。(改行コードのエスケープ)
echo -e 'A\nB\nC' \ | grep 'B' \ > result.txt
関数の定義と実行もできる。
Func() { echo -e 'A\nB\nC' | grep 'B' > result.txt; }; Func
ただし改行コードを途中に含めることはできない。文の区切りを改行にすると実行できない。
> Func() { \ > local INPUT=$(echo -e 'A\nB\nC') \ > echo "$INPUT" | grep 'B' > result.txt \ > } \ > Func; bash: 予期しないトークン `;' 周辺に構文エラーがあります
;
を使って複数文を1行で書けば実行できる。
Func() { local INPUT=$(echo -e 'A\nB\nC'); echo "$INPUT" | grep 'B' > result.txt; }; Func
なお、;
を&&
にしても良い。
Func() { local INPUT=$(echo -e 'A\nB\nC') && echo "$INPUT" | grep 'B' > result.txt; }; Func
改行エスケープを使うと以下。(文の終端を;
で表し、\
で改行エスケープする)
Func() { \ local INPUT=$(echo -e 'A\nB\nC'); \ echo "$INPUT" | grep 'B' > result.txt; \ }; \ Func;
シェルスクリプト
一行目にはshebang (シバン)を書く。
file.sh
#!/bin/bash echo -e 'A\nB\nC' | grep 'B' > result.txt
#!/bin/bash Func() { echo -e 'A\nB\nC' | grep 'B' > result.txt; }; Func
複数の文を連続して実行できる。(行末に; \
不要)
#!/bin/bash Func() { local INPUT=$(echo -e 'A\nB\nC') echo "$INPUT" | grep 'B' > result.txt } Func
;
で文の終わりを示す。続けて次の文を書ける。これで一行にできる。
#!/bin/bash Func() { local INPUT=$(echo -e 'A\nB\nC'); echo "$INPUT" | grep 'B' > result.txt } Func
;
を使い関数定義も一行に。
#!/bin/bash Func() { local INPUT=$(echo -e 'A\nB\nC'); echo "$INPUT" | grep 'B' > result.txt; } Func
;
を使い関数の定義と実行も一行に。
#!/bin/bash Func() { local INPUT=$(echo -e 'A\nB\nC'); echo "$INPUT" | grep 'B' > result.txt; }; Func
ここまでくるとシェバンを除いた箇所をコマンドラインシェルとして実行できる。
set -Ceu
すると予期せぬ悲劇を防げるかもしれない。
#!/bin/bash set -Ceu Func() { local INPUT=$(echo -e 'A\nB\nC'); echo "$INPUT" | grep 'B' > result.txt; }; Func
フラグ | 説明 |
---|---|
-C |
>| としないとリダイレクト時に上書き防止エラーとなる |
-e |
エラー発生時に中断する |
-u |
存在しない変数を参照するとエラーになり終了する |