
簡単んなシェルプログラミングを組んでいます。
そこである問題にぶつかっています。
********************************************
int main()
{
int argc, n = 0;
pid_t pid;
int status;
char input[MAX_LEN], *argv[MAX_ARGS];
char path[30];
while (1) {
/* プロンプトの表示 */
++n;
printf("command[%d] ", n);
fgets(input, MAX_LEN, stdin);
/*
改行を除去し、 空白,タブ区切りでコマンド列に分割、argvに単語毎に格納
(処理は略)
*/
sprintf(path,"%s",argv[0]);//PATH取得
pid = fork();
/*#### 子プロセス ####*/
if(pid == 0){
execvp(path,argv);
exit(0);
}
/*#### 親プロセス処理 ####*/
} else {
wait(&status);
}
}//while
}//main
としています。
ここで
ls
ps
rm
mkdir
emacs
などのコマンドは普通につかえるのですが、
cd ..
や、
mkdir test
cd test
としてもそのディレクトリへ移動することができません。どうすればいいでしょうか?このプログラムをうごかしたままディレクトリを移動することは可能でしょうか?
No.5ベストアンサー
- 回答日時:
おおよそ、他の方が書かれてますが、カレントディレクトリはプロセス固有の値で親から子へは継承されますが、子プロセス内で変更しても親へは伝わりません。
対応としては、コマンドがcdであることをチェックして、その場合は、fork&exec でなく、自分のプロセス内でchdirというシステムコールでカレントディレクトリを変更します。
環境変数PWDの話が出ていますが、カレントディレクトリと環境変数PWDには直接の関係がありません。PWDも変更したいならさらにsetenvサブルーチンで変更します。
話は変わって、
>execvp(path,argv);
>exit(0);
となっていますが、execvpの次の文が実行されるのはexecvpが失敗した時(pathで指定したファイルが無い等)なので、エラーメッセージを出したほうが良いでしょう。最初にそうしていれば、cd を入力するとエラーになる(cdはシェル組み込みコマンドで、cdというファイルは無いため)ので気づいたかも。
つまり、実は cd test と入れたときには子プロセスでtestにカレントディレクトリが移って親に反映しなかったわけではなく、execvpが失敗してexit(0)で子プロセスが終了していたと思われます。いずれにせよ対応は上に書いた通りでOKです。
シェルには多くの組み込みコマンドがあるので、それらのどこまで組み込むかが考えどころですね。cd のように組み込み処理が必須のコマンドもあれば、echo や test のようにコマンドファイルとしても存在するのに速度向上のために組み込みコマンドになっているものと二通りあります。
No.6
- 回答日時:
何か結局私が混乱させていたようですので役に立つか分かりませんがcdの引数無しでホームに移る部分書いておきます。
お騒がせしました。
if(argv[1] == NULL){
if(chdir(getenv("HOME")) <0)
perror("cd");
}
else{
if(chdir(argv[1]) <0)
perror("cd");
}
No.4
- 回答日時:
なんか私はいろいろ勘違いしていたようですね。
どうやら断食中で頭がぼーっとしているようです。
環境変数PWDの問題じゃないんですがカレント作業ディレクトリは継承されています。
どのように継承されてるかはちょっと私には分かりませんが・・・。
cdってshに組み込まれてるんですよねたしか。
だから扱いが難しそうですね。
難しそうですがUNIXのシェルのソースを見てみるのも手だと思います。
No.3
- 回答日時:
ummuさんの言われている通り、コマンドcdに関しては、子プロセスにforkして実行するのではなく、カレントプロセス内で実行する必要があります。
子プロセスでcdしても、親プロセス(=shellとして機能している方)には影響しないので。
which cdの結果を見ると、分かるかも。
No.1
- 回答日時:
前の質問で全然回答になっていなくて混乱させてしまったものと思われます。
すいません。同じもの書いてみましたが引数をとれると思います。
argvへの格納がおかしいのでは?
cdに関してですが毎回新たに子プロセスを生じているため子プロセスは親プロセスの環境変数PWDを継承しています。
このプログラムでは別にforkする必要が無いように思えます。
この回答への補足
再びご回答ありがとうございます
>>argvへの格納がおかしいのでは?
argvの中身を確認したところ、 cd testとしたところ、
argv[0]=cd,
argv[1]=test
と格納されていましたので、ここは大丈夫だと思います。
>>cdに関してですが毎回新たに子プロセスを生じているため子プロセスは親プロセスの環境変数PWDを継承しています。このプログラムでは別にforkする必要が無いように思えます
はじめ親プロセスにexecvpを記述したところ、プログラム起動後、一回のコマンドでプログラムが終了してしまいました。なので子プロセスを生成しないと、exec系でこのプログラムが終わってしまうようなんです。まだforkを使い始めたばかりで知識があまりないのですが。以下のように把握してよろしいでしょうか。
このプログラムだとcdのコマンドは子プロセスで実行する事になる。その後に行うコマンドは、親プロセスから継承した環境変数をもつ新たに生成された子プロセスだから、また同じフォルダにいることになる。
もしそうであれば何か解消方法はあるでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- Mac OS PATHを使ってcdなどで簡単に移動できるようになりたい 3 2023/05/13 14:22
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
プロセスIDの取得方法について
-
sleep関数の精度について
-
C#でのbatファイル実行結果取得
-
非表示になったエクセルは?
-
Process.Startの戻り値を後で取得
-
execvpでのcdコマンドについて。
-
プロセスIDからウィンドウハ...
-
常駐するアプリケーションを初...
-
WSH.Runで待機できません
-
c言語でプロセスIDを調べたい
-
Windowsでのfork方法
-
VB6.0 SHELLで起動...
-
powershellでプロセスIDの変数化
-
警告『 別のプロセスで使用され...
-
CreateProcess時の実行ユーザ変...
-
C++でシェルを起動
-
OSPFでプロセスを分ける意義に...
-
vb.netでEXCEL起動がうまくでき...
-
バッチファイルでPINGログ取得
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
C#でのbatファイル実行結果取得
-
プロセスIDの取得方法について
-
タスクマネージャーのプロセス...
-
explorer.exeが異様にメモリを食う
-
ADOでアクセスのレコードに...
-
プロセスのアタッチ・デタッチ...
-
怪しいプロセス教えてください。
-
c言語でプロセスIDを調べたい
-
vb.netでEXCEL起動がうまくでき...
-
SendMessageが失敗するときがある
-
VB6.0 SHELLで起動...
-
AppActivate関数について
-
プロセスIDからウィンドウハ...
-
非表示になったエクセルは?
-
Linuxでのスレッド間メッセージ...
-
起動中のEXCELファイル(EXCEL...
-
IISがフリーズ
-
OSPFでプロセスを分ける意義に...
-
特定ユーザーのプロセス情報を...
おすすめ情報