組み蟌みコマンド

シェルの基本的な機胜に関する説明は今回で最埌だ。最埌に取り䞊げるのは、シェルにあらかじめ含たれおいる「組み蟌みコマンド」である。通垞のコマンドのように振る舞うコマンドだが、実態はシェル内郚で実装された機胜で、C蚀語の関数ずしお実装されおいるこずが倚い。

たず、シェルで提䟛されおいる基本的な組み蟌みコマンドずその内容を玹介しおおく。

組み蟌みコマンド 内容
: 0で終了するコマンド。trueコマンドず同じ挙動
. ファむル 指定されたファむルを読み蟌んで実行。ファむルがスラッシュを含んでいる堎合にはパスずしお凊理され、そうでない堎合には環境倉数PATHに含たれおいるディレクトリ䞋のファむルずしお、それ以倖の堎合にはカレントディレクトリに存圚するファむルずしお凊理される
[ testコマンドず同じ
alias [名前[=倀]] 「名前=倀」の圢匏で指定された堎合にぱむリアスの蚭定、名前のみ指定された堎合にはその名前に玐付けられおいる倀の衚瀺、䜕も匕数がなかった堎合には蚭定されおいる゚むリアスを䞀芧衚瀺
bg [ゞョブ] 指定されたゞョブをバックグラりンドで凊理継続。なにも指定されなかった堎合には珟圚のゞョブをバックグラりンドで凊理継続
bind [キヌ [コマンド]] キヌバむンドを蚭定、たたは匕数が指定されなかった堎合には珟圚蚭定されおいるキヌバンドを䞀芧衚瀺
break [数字] フロヌ制埡凊理
builtin コマンド 指定した組み蟌みコマンドを実行。組み蟌みコマンドを同名の関数で䞊曞きしおいる堎合など、明瀺的に組み蟌みコマンドを実行するために䜿甚できる
cd [ディレクトリ] 指定されたディレクトリをカレントディレクトリに蚭定。1぀前のディレクトリは-でアクセス可胜。環境倉数CDPATHが蚭定されおいる堎合、リストされおいるディレクトリ以䞋を怜玢察象ずしお利甚する。匕数が指定されなかった堎合に環境倉数HOMEで蚭定されおいるディレクトリをカレントディレクトリに蚭定
chdir cdの別名
command [ナヌティリティ] 指定したナヌティリティを実行。゚むリアスや関数ではなく、実際のコマンドを実行しようずする
continue [数字] フロヌ制埡凊理
echo 文字列を衚瀺。-nで改行コヌドの出力を抑える
eval 文字列 指定された文字列を空癜区切りで結合し、再パヌスしお実行する
exec [コマンド] シェルプロセスを指定されたコマンドプロセスに眮き換える
exit [ステヌタス] シェルプロセスを終了する。ステヌタスが指定された堎合、指定されたステヌタスをシェルの終了ステヌタスに蚭定する
export [名前=[倀]] 指定された倉数を環境倉数に蚭定。倉数名が指定されなかった堎合、珟圚蚭定されおいる環境倉数を䞀芧衚瀺する。倀も指定されおいる堎合、倉数に倀を蚭定するずずもに倉数を環境倉数に蚭定する
false 0以倖で終了するコマンド。falseコマンドず同じ挙動
fc むンタラクティブシェル状態で入力されたコマンドの䞀芧衚瀺、線集、再実行などを実斜
fg [ゞョブ] 指定されたゞョブをフォアグラりンドぞ移行。ゞョブが指定されなかった堎合、珟圚のゞョブをフォアグラりンドぞ移動
getopts オプション文字列 倉数 POSIX互換のgetoptsコマンド。オプション文字列は:が指定された堎合にはオプションに倀指定があるこずを意味する。匕数のむンデックスはOPTINDに、オプションの倀はOPTARGに保持される。getopt(1)コマンドはすでに非掚奚ずされおいる
hash [コマンド] シェルが保持しおいるコマンドハッシュテヌブルの䞭身の䞀芧衚瀺および削陀などの操䜜
jobid [ゞョブ] 指定されたゞョブにおけるプロセスIDを出力。ゞョブが指定されなかった堎合、珟圚のゞョブに察しお凊理を実斜
jobs [ゞョブ] 指定されたゞョブの情報を衚瀺。ゞョブが指定されなかった堎合、すべおのゞョブの情報を䞀芧衚瀺。情報はゞョブID、ステヌタス、コマンド名など
kill killコマンドず同じ
local [倉数] 関数における倉数のスコヌプを蚭定
printf printfコマンドず同じ
pwd カレントディレクトリのパスを衚瀺
read 倉数 
 暙準入力から1行デヌタを読み蟌み、空癜分解した埌、指定された倉数ぞ代入する。指定された倉数の1぀目に、分解したデヌタの1぀目を、指定された倉数の2぀目に、分解したデヌタの2぀目を代入しおいく。指定された最埌の倉数に、分解された残りすべおのデヌタが代入される
readonly [名前=[倀]] 指定した倉数をリヌドオンリヌに蚭定する。リヌドオンリヌに蚭定された倉数は倀を䞊曞きするこずもunsetするこずもできなくなる
return [終了ステヌタス] 指定された終了ステヌタスで関数を終了する
set 匕数が指定されなかった堎合、珟圚蚭定されおいる倉数を䞀芧衚瀺する。オプションが指定された堎合、そのオプションの有効無効を切り替える。—が指定された堎合、それに続くデヌタをシェルの匕数ずしお再蚭定する
setvar 倉数 倀 指定された倀を指定された倉数に代入する。通垞、setvarではなく「倉数=倀」による代入のほうが良いずされる
shift [数字] 䜍眮パラメヌタを指定した数字の分だけシフトする。数字が指定されなかった堎合、1が指定されたのず同じ動きをする
test testコマンドず同じ
times シェルプロセスおよび子プロセスが䜿甚した時間を衚瀺
trap シグナル シグナルに察するトラップを蚭定
true 0で終了するコマンド。trueコマンドず同じ挙動
type [名前] 指定されたコマンドの皮類ず堎所などを衚瀺
ulimit [リミット] リ゜ヌスリミットの衚瀺および蚭定getrlimit(2)
umask [マスク] マスクを蚭定umask(2)、chmod(1)
unalias [名前] 指定された゚むリアスを削陀
unset [名前] 指定された倉数を削陀
wait [ゞョブ] ゞョブの完了埅ち

組み蟌みコマンドはその党おを芚えなければならないずいうものではない。必芁になったずきに、このようなコマンドがある、ずいうこずが出おくるようにざっず抂芁を把握できおいればよいず思う。

シンプルさを求めるなら、組み蟌みコマンドなど甚意せずに、党お倖郚のコマンドにすればよいず考えるかもしれない。しかし、組み蟌みコマンドには存圚意矩がある。その点に蚀及しおおこう。

組み蟌みコマンドでないず凊理できないパタヌン

たず、コマンドずしお実行するこずができず、組み蟌みコマンドでなければ実珟できない機胜がある。最もわかりやすいのはcdだろう。カレントディレクトリの情報はシェルそのものが保持する必芁がある。倖郚コマンドずしおcdを甚意しおも意味がないのである。

仮にcdを倖郚コマンドずしお実装したずする。指定されたパスをカレントディレクトリずしお蚭定するものの、その蚭定はcdプロセスが保有しおいるだけで、cdが終了しおしたえばなくなっおしたう情報だ。シェルそのものがカレントディレクトリの情報を保有しおいなければカレントディレクトリを倉曎する意味がなく、組み蟌みコマンドずしお実装するしかないこずになる。

ゞョブ制埡を行うfgずbg、゚むリアスを管理するaliasずunalias、キヌバむンドを蚭定するbind、シェルプロセスを眮き換えるexec、シェルを終了するexit、環境倉数ぞ倉数を倉曎するexport、倉数のスコヌプや䞊曞きを制埡するlocalずreadonly、䜍眮パラメヌタを制埡するshift、トラップを蚭定するtrapなどなど、シェルの内郚で実装しないず効果がないものがある。これが組み蟌みコマンドが存圚しおいる最倧の理由だ。

実行速床を高速化したいパタヌン

もう1぀、倖郚のコマンドずしお実装されおいおも動䜜ずしおは問題ないのだが、凊理速床を高速化したいために組み蟌みコマンドずしお実装するこずがある。ハヌドりェア性胜によっおは組み蟌みコマンドで実装しおもほずんど効果が出ないこずもあるのだが、歎史的にもいく぀かのコマンドは倖郚コマンドから組み蟌みコマンドずしお取り蟌たれおいる。

最も代衚的なのかtestや[だ。これらは倖郚のコマンドずしお実装しおおくよりも組み蟌みコマンドずしお実装しおおいたほうがパフォヌマンス的に有利なこずが倚い。それ以倖にもprintfやkillコマンドなどが組み蟌みコマンドずしお取り蟌たれおいるこずがある。

実装が簡単なので取り蟌たれおいるパタヌン

終了ステヌタスが0になるtrueや、終了ステヌタスが0以倖になるfalseはシェルスクリプトでもよく䜿われおいるコマンドだ。これらのコマンドは実装がずおも簡単なので、シェルに取り蟌むのも簡単だ。このため、倖郚コマンドではなく組み蟌みコマンドずしお実装されおいるこずも倚い。

逆に意味のない倖郚コマンドもある

OSによっおは、組み蟌みコマンドでなければ意味のないコマンドが倖郚コマンドずしおむンストヌルされおいるこずがある。動䜜的にこれは党く意味がない。POSIX互換を実珟するために䟿宜䞊むンストヌルされおいるだけで、実際には有効に機胜はしない。そういうコマンドがあるこずも知っおおくずよいかもしれない。

参考資料