シェル@ユーティリティ¶
はじめに¶
本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。
01. シェルとは¶
仕組み¶
標準入力からの入力を解釈し、Linuxカーネルを操作する。
また、Linuxカーネルの処理結果を解釈し、標準出力/標準エラー出力に出力する。
基本的には、いずれのシェルも同じ仕組みである。

01-02. 起動方法の種類¶
ログインシェル¶
▼ ログインシェルとは¶
資格情報を必要とし、認証後に最初に起動するシェルのこと。
パスワードは、/etc/passwdファイルに設定されている。
▼ su -¶
特定のユーザーで認証し、シェルを起動する。
# ハイフンオプション有り
$ su - <ユーザー名>
▼ bash --login¶
現在のユーザーで認証し、シェルを起動する。
# --loginオプション有り
$ bash --login
▼ ssh¶
SSH公開鍵認証で認証し、シェルを起動する。
$ ssh
インタラクティブシェル¶
▼ インタラクティブシェルとは¶
資格情報を必要とせず、最初に起動するシェルのこと。
▼ su <ユーザー名>¶
特定のユーザーで、認証なしでシェルを起動する。
# ハイフンオプション無し
$ su <ユーザー名>
▼ bash¶
現在のユーザーで、認証なしでシェルを起動する。
# --loginオプション無し
$ bash
非インタラクティブシェル¶
▼ 非インタラクティブシェルとは¶
シェルスクリプトを指定して実行するシェルのこと。
▼ bash -c¶
$ bash -c foo.sh
確認方法¶
現在の起動方法の種類は、変数の『$0』に格納されたシェルスクリプトのファイル名から確認できる。
$ echo $0
sh # インタラクティブシェル
# ログインシェルを起動する。ハイフンオプションがあることに注意する。
$ sudo su -
Last login: Mon Jun 20 13:36:40 JST 2022 on pts/0
[root@<IPアドレス> bin] $ echo $0
-bash # ログインシェルの場合、シェルの前にハイフンが付く。
補足として、もしシェルスクリプト内でこれを実行した場合は、これのファイル名を取得できる。
#!/bin/sh
# foo.shファイル
echo $0 # foo.sh
シェルの種類¶
▼ 系譜¶

▼ 設定ファイル¶
シェルを起動するとき、各種設定ファイルが読み込まれる。
ファイルが存在しなければ、自身で作成する。
| bashの場合 | zshの場合 | 読み込まれるタイミング |
|---|---|---|
| なし | ~/.zshenvファイル |
ログインシェル、インタラクティブシェルの起動時 |
~/.bash_profileファイル |
~/.zprofileファイル |
ログインシェルの起動時 |
~/.bashrcファイル |
~/.zshrcファイル |
ログインシェルの起動時。ただし、zshではインタラクティブシェルの起動時も含む。 |
~/.bash_loginファイル |
~/.zloginファイル |
ログインシェルの起動時。profileファイルと機能が重複するため、個人的には使用しない。 |
~/.bash_logoutファイル |
~/.zlogoutファイル |
exitコマンド時 |
▼ 確認方法¶
現在使用しているシェルを確認する。
$ echo $SHELL
/bin/zsh
変数¶
▼ 変数スコープと親子プロセス¶
シェルでは、変数のスコープがプロセスの親子関係によって決まる。

▼ シェル変数¶
現在実行中のプロセスのみで有効な変数のこと。
そのため、sourceコマンド以外の方法で実行されたシェルスクリプトでは、親プロセスで定義したシェル変数を使用できない。
#!/bin/bash
# foo.shファイル
echo "${FOO}"
$ FOO=foo # シェル変数を定義する。
$ bash foo.sh
# 出力されない
補足として、標準出力に対する出力をシェル変数に代入することもできる。
FOO=$(echo "foo")
▼ 環境変数¶
現在実行中のプロセスと、その子プロセスでも有効な変数のこと。
そのため、シェルスクリプトの実行コマンドに限らず使用できる。
#!/bin/bash
# foo.shファイル
echo "${FOO}"
$ export FOO=foo # 環境変数を定義する。
$ bash foo.sh
foo # 出力される
▼ 置換してから出力する¶
変数内の文字列を置換してから出力できる。
$ VERSION=1.0.0 # シェル変数を定義する。
# 文字列内の全てのドットをハイフンに置換する
echo "${VERSION//\./-}"
02. セットアップ¶
インストール¶
▼ apkリポジトリから¶
ほとんどのOSで、bashコマンドはプリインストールされているが、Alpine Linuxではシェル以外を別途インストールが必要である。
$ apk add bash
03. 終了ステータス¶
終了ステータスとは¶
プロセスは別の新しいプロセスを作成できる。
子プロセスの終了時に、親プロセスに終了ステータス (0〜255) が返却される。
終了ステータスの種類¶
| 値 | 意味 | エラーの原因 | 発生例 |
|---|---|---|---|
0 |
正常な完了 | - | - |
1 |
一般的なエラー | 構文エラーではないが、ロジックが誤っている可能性がある。 | $ let "var 1 = 1 / 0" |
2 |
シェルビルトインな機能の誤用 | シェルの構文や権限が誤っている可能性がある。 | $ empty_function(){} |
126 |
呼び出したコマンドが実行できなかった時 | 権限やその他の理由でコマンドを実行できてない可能性がある。 | $ /dev/null |
127 |
コマンドが見つからない時 | バイナリファイルの$PATHの未設定や、コマンドのタイポの可能性がある。 |
$ illegal_command |
128 |
exitコマンドに不正な引数を渡した時 |
exitコマンドに0〜255以外の整数を渡している可能性がある。 |
$ exit 3.14159 |
128 + n |
シグナル nで致命的なエラー |
killがシグナルnで実行された可能性がある。 |
$ kill -9 $PPID( 128 + 9 = 137で終了) |
128 + 2 |
スクリプトが Ctrl+Cで終了 |
Ctrl+Cはシグナル2で終了するため、Ctrl+Cが実行された可能性がある。 (128 + 2 = 130) |
Ctrl+C |
255 |
範囲外の終了ステータス | exitコマンドに0〜255以外の整数を渡している可能性がある。 |
$ exit -1 |
trueコマンド¶
trueコマンドを使用することにより、処理が途中で成功するか失敗するか (終了コードが0か0以外か) にかかわらず、処理を続行できる。
これは、複数の同じような処理を実行したい場合に役立つ。 (例:静的解析ツールに、異なるバージョンのパラメーターを渡して、同じ処理を連続的に実行する)
#!/bin/bash
# ここで失敗すると、終了コードが0以外でシェルスクリプトの処理を中断する
echo foo
echo bar
#!/bin/bash
# ここで失敗しても、終了コードが0になり、シェルスクリプトの処理は続行される
echo foo || true
echo bar
$?¶
コマンドの終了コードを出力する
$ echo "" ; echo $?
0 # 終了コードが 0 である
04. コマンドの実行タイミング¶
順次実行¶
▼ 終了ステータスがいずれであっても¶
連結したコマンドを順次実行する。
前のコマンドがいずれかの終了ステータスで完了しない限り、後ろのコマンドを実行しない。
$ echo foo; echo bar; echo baz
▼ 終了ステータスが0の場合のみ¶
連結したコマンドを順次実行する。
前のコマンドが終了ステータスが0で完了しない限り、後ろのコマンドを実行しない。
$ echo foo && echo bar && echo baz
▼ 終了ステータスが0以外の場合のみ¶
連結したコマンドを順次実行する。
前のコマンドが終了ステータスが0以外で完了しない限り、後ろのコマンドを実行しない。
$ echo foo || echo bar || echo baz
並列処理¶
連結したコマンドを並列処理する。
前のコマンドが完了しない限り、後ろのコマンドを実行しない。
$ echo foo & echo bar & echo baz