質問: {"/bin/cd","test", NULL}; execv("/bin/cd", str); if(errno != 0) perror(strerror(errno)); return -1; } ``` ### 試したこと `ls`や`mkdir`コマンドは↑のコードを変更して出来たのですが `cd`だけ出来ないです `/test`とかも試したのですが駄目でした どなたか分かる方教えていただけないでしょうか
回答: cdは「現在のプロセスの作業ディレクトリーを変更する」ものであって「サブプロセスで実行しても意味がない」ものの一つです。そのため、カレントディレクトリーを変更するようなプログラムを作ってそれをシェルから起動しても意図通りの動作にはなりません。そのため/bin/cdというコマンドは(あっても意味がないため)存在せず「No such file or directory」になるわけです。 シェルのcdはビルトインコマンドになっており、/binや/usr/binの下にある一般のコマンドのように「プロセスを生成してその中で動かす」のではなく実行中のシェルが直接chdirシステムコールを呼び出して現在のプロセスのカレントディレクトリーを変更する実装になっています。 同様にexportなども、サブプロセスを起動してその中で環境変数の変更を行っても、プロセス起動物のプロセスの環境変数が変化するわけではないので、ビルトインコマンドとして実装されています。 追記:上記の話では以下の知識がないと理解が難しいかもと気づきました。 Cでexecutableファイル(a.outみたいなもの)を作ってシェルから呼び出す場合、次のように動きます。 (1) シェルは子供プロセスをfork()で生成する (2) 生成された子供プロセスからexecv()で指定されたexecutableファイルを実行する つまりexecutableファイルは常に起動元のシェルの子供プロセスで実行されており、子供プロセスで行った「プロセス固有の情報」の変更は親プロセスには影響しません。カレントディレクトリーはプロセス固有の情報ですのでexecutableファイルで変更しても親プロセスにはなんら影響を及ぼすことができないということです。 なんか・・・わかりにくい説明でスミマセン