[英]Why does execvp only work for the first command entered in my shell?
[英]Why does wc command in execvp() return the wrong results when taking input from a pipe in my shell?
我正在為學習目的在 C 中編寫 shell ,並且我正在嘗試允許可變數量的管道。 一般來說,它似乎工作得很好。 但我注意到wc
命令有問題。
當我把另一個程序的 pipe 一些 output 放到wc
中時,就像ls | wc
ls | wc
它總是返回
1 3 35
不管我用pipe 進去吧。 當我 pipe 進入它們時,其他命令按預期工作。 在我正常的zsh
shell wc
工作正常。 我正在努力尋找問題所在。 我嘗試在分叉后添加waitpid
,但沒有骰子。
這是主要 function 中的main
shell 循環:
while (1) {
printf("\033[31;1mshell:\033[0m ");
line = read_cmds();
if (strstr(line, "|")) {
// check for pipes first
pipe_exec(line);
} else {
// we have a single command
tokens = split(line, " \t\r\n");
if (*tokens != NULL) shell_exec(tokens);
free(tokens);
}
}
這是循環執行命令的 function:
void pipe_exec(char *line)
{
int in, status;
int pipe_no; // keep track of ptr to bring it back to free
int pfd[2];
pid_t rc;
char **cmd, **pipe_cmds;
// split takes a string and splits into array of strings based on delimiter
pipe_cmds = split(line, "|");
in = 0;
pipe_no = 0;
while (*pipe_cmds) {
cmd = split(*pipe_cmds, " \t\r\n");
if (pipe(pfd) < 0) perror("pipe");
make_proc(in, pfd[1], cmd);
close(pfd[1]);
in = pfd[0];
pipe_cmds++; // move ptr ahead one
pipe_no++;
}
// move pointer back and free
pipe_cmds -= pipe_no;
free(pipe_cmds);
rc = fork();
if (rc == 0) {
if (in != 0) dup2(in, STDIN_FILENO);
execvp(*cmd, cmd);
}
}
然后上面的make_proc
調用的 make_proc function :
void make_proc(int in, int out, char **cmd)
{
pid_t rc;
rc = fork();
if (rc == 0) {
if (in != STDIN_FILENO) {
dup2(in, STDIN_FILENO);
close(in);
}
if (out != STDOUT_FILENO) {
dup2(out, STDOUT_FILENO);
close(out);
}
execvp(*cmd, cmd);
}
}
我在這里取出了一些錯誤檢查以節省空間。 任何幫助表示贊賞!
您執行最后一個命令兩次,pipe 它的第一個實例到第二個。 添加類似:
while (*pipe_cmds) {
cmd = split(*pipe_cmds, " \t\r\n");
if (!pipe_cmds[1]) {
break;
}
if (pipe(pfd) < 0) perror("pipe");
make_proc(in, pfd[1], cmd);
close(pfd[1]);
in = pfd[0];
pipe_cmds++; // move ptr ahead one
pipe_no++;
}
會阻止不必要的實例,盡管我寧願稍微重構一下這個 function。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.