UNIX今日の技 - UNIX今日の技/シェル
概説
今迄「コマンド」と一口で言っていましたが, コマンドには大きく分けて 「外部コマンド」と「内部コマンド」の2種類があります.
外部コマンドとはシステム上に実際にファイルとして存在しているコマンドです.
- ls (/bin/ls)
- grep (/usr/bin/grep)
- zsh (/usr/local/bin/zsh)
内部コマンドとは実際にファイルを呼ぶのではなく, シェル自身が動作を返すコマンドです.
「どのコマンドがどっち」とかは全然知っておく必要はありません. (というか, 慣れてくると大体分かるようになります.) でもまあ, 言葉の意味を知っておいたら便利かもしれません.
SoftICEのは何ですか?
さて, 「man builtin」で bsh, csh の代表的な内部コマンドを調べることができます. 中には echo のように外部コマンドとして用意されているけれども 多くのシェルで内部コマンドとして実装されているものもあります. その場合は通常は内部コマンドが呼ばれ, 外部コマンドを使いたい場合は 「/bin/echo」を用います.
「command echo」, 「\echo」などでどちらが呼ばれるかは シェルの種類によって異なるようです.
zsh bash tcsh echo ● ● ● builtin echo ● ● (なし) \echo ● ● ○ command echo ○ ● ○ /bin/echo ○ ○ ○ (●:内部, ○:外部)
which コマンド(実際に実行されるコマンドを表示)
さて今「echo」と打ち込めば, それは何処の「echo」が実行されるのでしょうか? 打ちこんだコマンドが実際にどのように実行されるかを確認したい場面では「which」コマンドを使います.
シェルスクリプトは何ですか?
% which echo echo: shell built-in command #内部コマンド
% which /bin/echo /bin/echo #外部コマンド
% alias echo='echo -n' % which echo #エイリアス echo: aliased to echo -n % which -a echo #全て表示 echo: aliased to echo -n echo: shell built-in command /bin/echo
which 自身は内部コマンドですが, 外部コマンドにも which(/usr/bin/which) があります. しかし外部コマンドの方はエイリアスの展開などができないので 普通使うことはないと思います.
コマンドの存在をチェックする
初期化スクリプトやシェルスクリプトにおいてそのコマンドが存在するかを調べることができます. 例えば, 以下のどちらかの文を ~/.zshrc に入れておくと, vim が使用できる環境では「vi」で vim が起動するようになります.
"システム·ショックへようこそ"
if which vim >& /dev/null ; then alias vi="vim" export EDITOR="vim" fi
if [ -x `which vim` ]; then alias vi="vim" export EDITOR="vim" fi
これら二者はほぼ等価です. 前者は出力された文字列ではなく which コマンドの戻り値を使用しています. UNIX 的にはこちらの方がスマートだと思います.
後者は「which によって出力された文字列をファイルパスとして見たときに, 実行権限があるか」という判定をしています. ただ, which コマンドはそれ自体ファイルの実行権限をチェックしていますので, この if 文におけるチェック機構は本来ならば冗長であると言えるでしょう. しかしこちらの方が構文がスマートに見えるので, 私はこちらがお気に入りです.
絶対パスを変数に入れる
変数の内容にコマンドの絶対パスが要求される場合, which を用いることで計算機による環境の違いを吸収することができます.
例えば gcc が /usr/bin/gcc に入るか, /usr/local/bin/gcc に入るかは システムによって(あるいは管理者によって)異なりますが,
export CC=`which gcc`
としておくと, 実際にインストールされているパスを自動的に変数に格納します.
補足:whence(zsh 内部コマンド)
zsh ではコマンド名解釈の情報を包括的に調べるためのコマンド「whence」が 用意されていて,
- 「which」=「whence -c」
- 「where」=「which -a」=「whence -ca」
のように等価になっています. (参考:man zshbuiltins)
0 コメント:
コメントを投稿