ア | イ | ウ | エ | オ |
カ | キ | ク | ケ | コ |
サ | シ | ス | セ | ソ |
タ | チ | ツ | テ | ト |
ナ | ニ | ヌ | ネ | ノ |
ハ | ヒ | フ | ヘ | ホ |
マ | ミ | ム | メ | モ |
ヤ | ユ | ヨ | ||
ラ | リ | ル | レ | ロ |
ワ | ヰ | ヴ | ヱ | ヲ |
ン |
A | B | C | D | E |
F | G | H | I | J |
K | L | M | N | O |
P | Q | R | S | T |
U | V | W | X | Y |
Z | 数字 | 記号 |
カレントディレクトリを変更する、MS-DOSやUNIXのコマンド。
FreeBSDなどBSDや、あるいはBSDカーネルを使用または影響を受けているOS XやSolarisなどでは、外部コマンドとして /usr/bin/cd が存在する。
しかしこれは、内蔵コマンドのcdのような動作はしない。上述のように、/usr/bin/cd を実行しても呼び出したシェルとは別プロセスであるので、呼び出し元のシェルに影響を与えることはないからである。
ではなぜ存在するのか? は、FAQであるらしい。
BSDは、この間抜けなPOSIXに準拠するために、このような無意味なコマンドを用意していることになる。
なお、FreeBSDなどの場合、その他のコマンドと共有のシェルスクリプトがハードリンクとなっている。
#!/bin/sh # $FreeBSD: release/9.1.0/usr.bin/alias/generic.sh 151635 2005-10-24 22:32:19Z cperciva $ # This file is in the public domain. builtin ${0##*/} ${1+"$@"}
builtinは、特定の環境でエラーが出ないように含めたもので、実質的に機能するのは次の部分。
${0##*/} ${1+"$@"}
最初の部分は「/usr/bin/cd」である ${0} から最後の / 以降を取り出す。つまり「cd」を得る処理である。
後の部分は「"$@"」と同様の動作で、引数部分がセットされることになるが、引数がない場合に「"$@"」が「""」になってしまうことを避けるため、技巧が凝らされている。
結果としてこれは、シェルを起動し、その中の内部コマンドであるcdを実行する。
しかし他のプロセスで動作する以上は、いくら頑張ってみても元のプロセスに影響が及ぶことはない。
では外部コマンドは絶対無理なのかというとそうでもなく、gdbなどを使えば例外的に可能である。
Linuxのbashで確認した限りでは、次のように動作した。
$ pwd /home $ gdb -p $$ -q -n <<<'call chdir("/tmp")' >/dev/null
カレントディレクトリを確認する。
$ pwd /home
変化していないように見えるが、ls コマンドなどは /tmp 以下が表示できるので、カレントディレクトリが変化したことは間違いない。そこで、procfsから確認する。
$ file /proc/self/cwd /proc/self/cwd: symbolic link to `/tmp'
プロセスのカレントディレクトリは確かに変わっていた。
シェル内蔵コマンドではなく、外部コマンドのpwdを使ってみる。
$ /bin/pwd /tmp
ここから、シェル内蔵コマンドのpwdは、プロセスのカレントディレクトリ情報を逐一確認して表示しているのではなく、シェル内蔵コマンドのcdで設定した内容をそのまま表示していることが分かる。
外部から強引に変更されることを想定していないためと思われる。
コメントなどを投稿するフォームは、日本語対応時のみ表示されます