[英]Redirecting I/O in a custom shell program written in C
我一直在研究自定義 shell 腳本,並且在使用下面給出的代碼重定向輸出時遇到了一個小錯誤。 在當前狀態下,代碼運行良好,但是當傳遞給 execvp args 時會拋出錯誤,例如 : (ls ">" 沒有這樣的文件或目錄)。 我知道這是因為它將整個 args[] 傳遞給不工作的父 shell。 添加 args[j] = NULL 會去掉 "<"/">" 從而修復錯誤,但也會導致重定向不再起作用。 我怎樣才能讓它不拋出錯誤但也能正常工作? 我已經閱讀了這個問題的多個版本,但似乎找不到答案。 在此先感謝您的幫助。
switch (fork()){
case -1:
fprintf(stderr, "error forking");
case 0://CHILD
for(int j = 0; j < size; j++){
if(!strcmp(args[j], "<")){//looking for input character
++ext;
if((in = open(args[j+1], O_RDONLY)) < 0){//open file for reading
fprintf(stderr, "error opening file\n");
}
dup2(in, STDIN_FILENO);//duplicate stdin to input file
close(in);//close after use
//args[j] = NULL;
}//end input chech
if(!strcmp(args[j],">")){//looking for output character
++ext;
out = creat(args[j+1], 0644);//create new output file
dup2(out, STDOUT_FILENO);//redirect stdout to file
close(out);//close after usere
// args[j] = NULL;
}//end output check
if(!strcmp(args[j], ">>")){//looking for append
++ext;
int append = open(args[j+1],O_CREAT | O_RDWR | O_APPEND, 0644);
dup2(append, STDOUT_FILENO);
close(append);
// args[j] = NULL;
}
}//end loop
execvp(args[0],args);//execute in parent
fprintf(stderr, "error in child execi \n");//error
exit(0);
default://PARENT
wait(&status); //wait for child to finish
}//end switch
當您解析重定向(例如<
、 >
、 >>
)並執行open/dup2
,您必須將它們從傳遞給execvp
的參數列表中刪除。
因此,鑒於您的args
,您需要第二個(例如args_clean
)參數列表,您只需復制程序名稱及其參數。
並且,您需要額外增加j
以跳過args
的重定向文件(即僅執行j + 1
並不等效)。
這是清理后的子代碼[請原諒無償的風格清理]:
char *args_clean[size];
int cleanidx = 0;
for (int j = 0; j < size; j++) {
if (!strcmp(args[j], "<")) { // looking for input character
++j;
if ((in = open(args[j], O_RDONLY)) < 0) { // open file for reading
fprintf(stderr, "error opening file\n");
}
dup2(in, STDIN_FILENO); // duplicate stdin to input file
close(in); // close after use
continue;
} // end input chech
if (!strcmp(args[j], ">")) { // looking for output character
++j;
out = creat(args[j], 0644); // create new output file
dup2(out, STDOUT_FILENO); // redirect stdout to file
close(out); // close after usere
continue;
} // end output check
if (!strcmp(args[j], ">>")) { // looking for append
++j;
int append = open(args[j], O_CREAT | O_RDWR | O_APPEND, 0644);
dup2(append, STDOUT_FILENO);
close(append);
continue;
}
args_clean[cleanidx++] = args[j];
} // end loop
args_clean[cleanidx] = NULL;
execvp(args_clean[0], args_clean); // execute in parent
fprintf(stderr, "error in child execi \n"); // error
exit(0);
另外,請在此處查看我的答案,了解與管道類似的內容: fd 泄漏、自定義外殼
而且,對於完整的 shell,請參閱我的答案: Implementing input/output redirection in a Linux shell using C並查看嵌入式 pastebin 鏈接
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.