シェルにも種類がある

Bashは多くのUnix系システムでデフォルトのシェルとして採用されているが、他にもZshやKsh、Csh、Tcshなど様々なシェルが存在する。

  • 1990 Zsh - Bourne Shellベースに拡張したシェル
  • 1989 Bash - GNUプロジェクトによって開発されたシェル
  • 1983 Ksh - Korn Shellとも呼ばれ、Bashの前身となったシェル
  • 1983 Tcsh - Cshをベースに拡張したシェル
  • 1977 Csh - C言語の構文に似たシェル

実行ファイルの場所を調べる

多くのシェルで which コマンドを使用して、コマンドが存在するかどうかを確認することができる。

which は、環境変数 PATH に列挙されたディレクトリを順に探し、引数に指定した名前の実行ファイルが見つかったとき、そのパスを標準出力へ書き出す。

見つからない場合は標準エラーへメッセージを出し、終了ステータスは 0 以外になる。

$ zsh -c 'which mv'
/bin/mv
$ bash -c 'which mv'
/bin/mv
$ ksh -c 'which mv'
/bin/mv
$ tcsh -c 'which mv'
/bin/mv
$ csh -c 'which mv'
/bin/mv

スクリプトで「このコマンドが使えるか」だけを判定したい場合は出力を捨てて終了ステータスだけを見る。

if which jq >/dev/null 2>&1; then
  echo 'jq is available'
else
  echo 'jq is not available'
fi

組み込みコマンドに対して実行する

組み込みコマンドに対して実行するとパスを返す場合と組み込みコマンドであることを返す場合がある。

$ zsh -c 'which cd'
cd: shell built-in command
$ bash -c 'which cd' || echo 'not found'
/usr/bin/cd
$ ksh -c 'which cd' || echo 'not found'
/usr/bin/cd
$ tcsh -c 'which cd'
cd: shell built-in command.
$ csh -c 'which cd'
cd: shell built-in command.

コマンドによってはエラーになるシェルもある。

$ zsh -c 'which let'
let: shell built-in command
$ bash -c 'which let' || echo 'not found'
not found
$ ksh -c 'which let' || echo 'not found'
not found
$ tcsh -c 'which let'
let: Command not found.
$ csh -c 'which let'
let: Command not found.

エイリアスに対して実行する

エイリアスに対して実行するとzshでのみエイリアスの定義を返す。

$ zsh -c 'alias ll="ls -l"; which ll'
ll: aliased to ls -l
$ bash -c 'alias ll="ls -l"; which ll' || echo 'not found'
not found
$ ksh -c 'alias ll="ls -l"; which ll' || echo 'not found'
not found
$ tcsh -c 'alias ll="ls -l"; which ll'
ll: Command not found.
$ csh -c 'alias ll="ls -l"; which ll'
ll: Command not found.

関数に対して実行する

関数に対して実行するとzshでのみ関数の定義を返す。tcshcshは関数に対応していないため定義のタイミングでエラーになる。

$ zsh -c 'f() { echo foo; }; which f'
f () {
        echo foo
}
$ bash -c 'f() { echo foo; }; which f' || echo 'not found'
not found
$ ksh -c 'f() { echo foo; }; which f' || echo 'not found'
not found
$ tcsh -c 'f() { echo foo; }; which f'
Badly placed ()\'s.
$ csh -c 'f() { echo foo; }; which f'
Badly placed ()\'s.

予約語に対して実行する

予約語に対して実行するとzshtcshcshで組み込みコマンドであることを返す。bashkshは予約語に対応していないためエラーになる。

$ zsh -c 'which if'
if: shell reserved word
$ bash -c 'which if' || echo 'not found'
not found
$ ksh -c 'which if' || echo 'not found'
not found
$ tcsh -c 'which if'
if: shell built-in command.
$ csh -c 'which if'
if: shell built-in command.