シェルとは
- ユーザーとカーネルの間のインターフェイス。ユーザーが入力したコマンドや文字列のメタキャラクタを解釈するインタープリタ。
ログインシェル
- ユーザーがシステムへログインしたときに起動するシェル。ログインするシェルを変更する場合はchshコマンドを使用。
- ログインシェル上でさらに別のシェルを起動することができるが、ユーザーが使用することができるのは最後に起動したシェルのみ。
- ログインシェルと後に起動したシェルの見分け方はps -f。最初にハイフン「-」がついているシェルがログインシェルのプロセス。
$ ps -f
UID PID PPID C STIME TTY TIME CMD
xxx 13450 13449 0 21:26 pts/1 00:00:00 -bash
xxx 13476 13450 0 21:26 pts/1 00:00:00 bash
xxx 13499 13476 0 21:27 pts/1 00:00:00 ksh
xxx 13501 13499 0 21:27 pts/1 00:00:00 ps –f
シェルの種類
- 古いものから順にBourneシェル、Cシェル、Kornシェル、Bashとなる。
- BashはUNIX上のBourneシェル互換としてGUNより開発されたLinux標準シェル。
- LinuxでのBashの起動は$ shで(LinuxではBourneシェルはライセンス上使用できない為)。
- ↓確かにリンクがbashへと張られている(CentOSで実行)
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 7月 9 15:06 /bin/sh -> bash
シェルスクリプトの使いどころ
- Linuxコマンドの組み合わせで実現できる処理(grep, sort, sed, awk, etc…)であればシェルスクリプトを使用。特にテキスト行の処理など。
- 数値や文字列ごとの処理を使用する場合は型変換等の負荷のため実行速度が低下するため、C言語等の高級言語を使用するのが望ましい。
シェルスクリプトの作成と実行方法
- vi, vim等のテキストエディタで作成。対象のスクリプトファイルに実行権限を付与。
- chmod u+x xxxxxx.sh か、
- chmod 744 xxxxxx.sh でOK.
- 実行は ./xxxxxx.sh ただし、カレントディレクトリにpathが通っている場合は先頭の./は不要となる。
- スクリプトの1行目のシェルの指定(絶対パス)は、#!/bin/sh, #!/bin/bashのどちらを用いてもLinux上ではBashで実行される。
- 1行目を省略した場合は、LinuxではBashで実行される。
- #のみを記述すると、現在起動中のシェルと同じシェルで実行される。
コマンドの種類
- 組み込みコマンド:シェル内部のコマンド(cd, exitなど)
- 一般コマンド:実行形式ファイルのコマンド(cp, lsなど)。/binや/usr/binディレクトリ以下に実行ファイルが存在する。
- 組み込み・一般の判別にはtypeコマンドを使用する。
- 以下にtypeコマンドの実行例。
$ type cp
cp is /bin/cp
$ type cd
cd is a shell builtin
- 一般コマンドがシェルで実行されると、子プロセス上で実行される。
- 実行順序としては、一般コマンド実行時→親プロセスのforkシステムコールによる子プロセスの生成→親プロセスのwaitシステムコールによる子プロセスの処理実行待ち→子プロセスのexecシステムコールによりコマンドのロード→コマンドプログラムのexitシステムコールにより子プロセスの終了→親プロセスの後続の処理を実行…。
- 基本的にシェルスクリプトも実行時に特に指定がなければ子プロセスを生成し実行される。
- シェルの変数定義のスコープはプロセス毎。
入出力リダイレクション
- 標準入力(0)、標準出力(1)、標準エラー出力(2)。リダイレクト記号はそれぞれ<, 1>, 2>であるが、標準出力の1は省略可能のため、>で可能。
- 2>&1の場合は、コマンド実行時のエラーを標準出力(1)に割り当て。
- $ find / -name help > findlist 2>&1
パイプによるコマンドの連携
- パイプ「|」は→とみた方が直感的にわかりやすい。|の左で実行されたコマンドの出力をパイプの後に指定したコマンドの入力として使用。
- # grep Invalid /var/log/secure | wc –l
その他のシェルのメタキャラクタ
- 連続実行:1行内でのコマンドの連続実行をする場合はコマンド間にセミコロンを挿入「;」。(C言語のステートメント終了みたいだぁ)
- グループ化:()のコマンドを子プロセスを生成して実行。cd /; pwd ; lsの三種コマンドに括弧をつけるとカレントディレクトリを変更せずに実行結果を取得できる。
- 親プロセスの環境の変更したくない場合や複数コマンドの実行結果を出力したい場合に利用。