[解決済み] C 言語で fork/execvp を使って簡単なシェルを作成する
2022-03-01 15:22:16
質問
システムコールのfork()/execvp()を使って、C言語で簡単なシェルを開発する必要があります。今のところ、私のコードはコマンドを受け取り、strtokを使用して配列argvに分割し、それから私は子プロセスを作成し、コマンドを実行するためにforkを呼び出します。私は、ほとんどのコマンドが/bin/ディレクトリにあるubuntuでこれに取り組んでいるので、私はプログラム名(例えば/bin/ls)を追加し、execvpの最初の引数にそれを使用して、私はそれをargv配列に与えます。私のプログラムは、コマンド "ls" を入力すると動作しますが、他のコマンドや "ls -l" を試すと、 "ls: invalid option." が表示されます。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_LEN 1024
int main(){
char line[BUFFER_LEN]; //get command line
char* argv[100]; //user command
char* path= "/bin/"; //set path at bin
char progpath[20]; //full file path
int argc; //arg count
while(1){
printf("My shell>> "); //print shell prompt
if(!fgets(line, BUFFER_LEN, stdin)){ //get command and put it in line
break; //if user hits CTRL+D break
}
if(strcmp(line, "exit\n")==0){ //check if command is exit
break;
}
char *token; //split command into separate strings
token = strtok(line," ");
int i=0;
while(token!=NULL){
argv[i]=token;
token = strtok(NULL," ");
i++;
}
argv[i]=NULL; //set last value to NULL for execvp
argc=i; //get arg count
for(i=0; i<argc; i++){
printf("%s\n", argv[i]); //print command/args
}
strcpy(progpath, path); //copy /bin/ to file path
strcat(progpath, argv[0]); //add program to path
for(i=0; i<strlen(progpath); i++){ //delete newline
if(progpath[i]=='\n'){
progpath[i]='\0';
}
}
int pid= fork(); //fork child
if(pid==0){ //Child
execvp(progpath,argv);
fprintf(stderr, "Child process could not do execvp\n");
}else{ //Parent
wait(NULL);
printf("Child exited\n");
}
}
}
解決方法は?
無効なオプションは
fgets()
を保持します。
'\n'
Enterキーを押したとき、次のようにします。
if(!fgets(line, BUFFER_LEN, stdin))
break;
size_t length = strlen(line);
if (line[length - 1] == '\n')
line[length - 1] = '\0';
を呼び出そうとしたとき
ls -l
を渡すと
"-l\n"
をオプションとして指定したため、このようなメッセージになりました。
を変更する必要があります。
strcmp(line, "exit\n")
になります。
strcmp(line, "exit")
関連
-
[解決済み】エラー。非スカラー型への変換を要求された
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] scpを使ってリモートからローカルにフォルダをコピーするにはどうしたらいいですか?
-
[解決済み] シェルで、「2>&1」はどういう意味ですか?
-
[解決済み] LinuxのシェルスクリプトでYes/No/Cancelの入力を促すにはどうしたらいいですか?
-
[解決済み] Bashシェルスクリプトの入力引数の存在確認
-
[解決済み] Git上でシェルコマンドを実行する際に使用するSSH-keyの秘密鍵を指定する方法は?
-
[解決済み] シェルスクリプトでYYYY-MM-DD形式の日付にする
-
[解決済み] シェルスクリプトで部分文字列を別の文字列に置き換える
-
[解決済み】bashで1つのコマンドでシェル変数にデフォルト値を割り当てる。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】stdinとSTDIN_FILENOの違いは何ですか?
-
[解決済み】 `S_ISREG()` とは何ですか、そして何をするのですか?
-
[解決済み】ポインタと整数の比較で警告が出る
-
[解決済み】 strcpyとstrdupの比較
-
[解決済み】LEALアセンブリ命令は何をするのですか?
-
[解決済み】警告:組み込み関数'printf'の非互換な暗黙の宣言(デフォルトで有効]
-
[解決済み】C言語でint64_t型を表示する方法
-
[解決済み】エラー:呼び出されたオブジェクトは、関数または関数ポインタではない
-
[解決済み] execvp()の使用方法
-
[解決済み】なぜgets関数は危険で使ってはいけないのですか?