gpt4 book ai didi

c - Execvp 与 "ls -l | wc"一起工作,但因“ls -l|wc”而失败

转载 作者:太空宇宙 更新时间:2023-11-03 23:37:44 26 4
gpt4 key购买 nike

我正在编写一个 shell,目前正在执行管道进程。我能够运行 "ls -l | wc",但是当运行 "ls -l|wc" 时,进程失败。

我曾尝试使用 gdb 进行调试,但无法对其进行任何调试,因为它们看起来都等于相同的值(在解析后)。

运行 ls -l | 时wc 并在 parseCmdWithPipe 函数上设置断点并打印出我得到的局部变量:

argOne = {0x7fffffffdad0 "ls", 0x7fffffffdad3 "-l", 0x0}
argTwo = {0x7fffffffdad8 "wc", 0x0}

当运行 ls -l|wc 并在 parseCmdWithPipe 函数上设置断点并打印出局部变量时,我得到:

argOne = {0x7fffffffd9b0 "ls", 0x7fffffffd9b3 "-l", 0x0}
argTwo = {0x7fffffffd9b8 "wc", 0x0}

我用来解析和使用execvp的代码(第二个函数)

/* parse user input from fget */
int parseLine(char *line, char **argv) {
line[strlen(line) - 1] = '\0';
//This section tries to figure out if we have the case
//"ls -l|wc", if it does it makes a new string of "ls -l | wc"
int cmdType = 1;
int size = sizeof(line);
char tempLine[size + 3];
bool pipeSeen = false;
for (int i = 0; i < size; i++) {
if (line[i] == '|' && line[i - 1] != ' ') {
tempLine[i] = ' ';
tempLine[i + 1] = '|';
tempLine[i + 2] = ' ';
pipeSeen = true;
} else {
if (pipeSeen == true)
tempLine[i + 2] = line[i];
else
tempLine[i] = line[i];
}
}

if (pipeSeen == true) {
tempLine[size + 2] = '\0';
line = tempLine; // change "ls -l|ls to ls -l | wc"
}
/* parse line and store it in argv */
while (*line) {
while (*line == ' ')
*line++ = '\0';

//Figure out what type of command we may have
if (*line == '<')
cmdType = (cmdType == 3) ? 5 : 2;
else if (*line == '>' )
cmdType = (cmdType == 2) ? 5 : 3;
else if (*line == '|')
cmdType = 4;

*argv++ = line;
while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n')
line++;
}
*argv = '\0';
return cmdType;
}

void parseCmdWithPipe(char **argv) {
int size = getCmdSize(argv);
char val[1];
int pipePosition = 0;
for (int i = 0; i < size; i++) {
strcpy(val, argv[i]);
if (val[0] == '|') {
pipePosition = i;
break;
}
}

char *argOne[pipePosition + 1];
for (int i = 0; i < pipePosition; i++) {
argOne[i] = argv[i];
}
argOne[pipePosition] = '\0';

char *argTwo[size - pipePosition];
for (int i = 0; i < (size - pipePosition); i++) {
argTwo[i] = argv[i + pipePosition + 1];
}
argTwo[size - pipePosition - 1] = '\0';

int pfd[2], pid;
if (pipe(pfd) == 1)
syserror("Could Not create a pipe");

switch (pid = fork()) {
case -1:
syserror( "Fork Failed" );
case 0:
if (dup2(pfd[0], 0) == -1|| close (pfd[0]) == -1 || close (pfd[1]) == -1)
syserror("Failed to run dup2 or close pfd in second child");
execvp(argTwo[0], argTwo);
syserror("execvp unsuccessful in 2nd child");
}
....

我希望 "ls -l|wc" 给我相同的结果 "ls -l | wc" 给我

11      92     597

但实际输出是

execvp unsuccessful in 2nd child
(No such file or directory)

最佳答案

主要问题是int size = sizeof(line);它不计算 line 指向的字符串的大小和长度。 , 但仅评估为 char * 的大小.

你应该写int size = strlen(line);并且可能不会调用此变量 size ,但是 len相反。

代码太复杂,你不应该尝试在|两边插入空格符号,顺便说一句,你没有对 < 做同样的事情和 > .

关于c - Execvp 与 "ls -l | wc"一起工作,但因“ls -l|wc”而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54757028/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com