管道没有创建特定的管道描述符
我有一个项目在C上复制shell命令。其中一个命令是|这需要使用管道进行。我的其他命令有效,但我无法使(ls | sort)工作。它说, LS不能访问|:没有这样的文件或目录 LS不能排序访问:没有这样的文件或目录管道没有创建特定的管道描述符
我希望有人能帮助我弄清楚如何解决这个问题的管道?它开始试图做到这一点,所以我不必为每个命令做一个单独的管道,所以我通过for循环运行它。
执行大部分工作的功能是执行。 Runsource和Rundest在管道中进行信息的打开和传输。
void execute(char *cmdline)
{
int pid, async;
char *args[MAX_ARGS];
char *pargs[MAX_ARGS];
int i = 1;
int j;
int nargs = get_args(cmdline, args);
if (nargs <= 0)
return;
if (!strcmp(args[0], "quit") || !strcmp(args[0], "exit"))
{
exit(0);
}
int npargs = get_pipe(cmdline, pargs);
if (npargs > 1)
{
int pdes[2];
pipe(pdes);
for (j = 0; i < npargs; j++)
{
nargs = get_args(pargs[j], pargs);
runsource(pdes, j, pargs, npargs);
rundest(pdes, j + 1, pargs, npargs);
close(pdes[0]);
close(pdes[1]);
}
}
else
{
while (args[i] < args[nargs])
{
if (strcmp(args[i], ">"))
{
freopen(args[i + 1], "w", stdout);
args[i] = NULL;
}
if (strcmp(args[i], ">>"))
{
freopen(args[i + 1], "a", stdout);
args[i] = NULL;
}
if (strcmp(args[i], "<"))
{
freopen(args[i + 1], "r", stdin);
args[i] = NULL;
}
}
}
/* check if async call */
if (!strcmp(args[nargs - 1], "&"))
{
async = 1;
args[--nargs] = 0;
}
else
async = 0;
pid = fork();
if (pid == 0) /* child process */
{
execvp(args[0], args);
/* return only when exec fails */
perror("exec failed");
exit(-1);
}
else if (pid > 0) /* parent process */
{
if (!async)
waitpid(pid, NULL, 0);
else
printf("this is an async call\n");
}
else /* error occurred */
{
perror("fork failed");
exit(1);
}
}
int main(int argc, char *argv[])
{
char cmdline[BUFFSIZE];
for (; ;)
{
printf("COP4338$ ");
if (fgets(cmdline, BUFFSIZE, stdin) == NULL)
{
perror("fgets failed");
exit(1);
}
execute(cmdline);
}
return 0;
}
我看你有没有特殊的代码来处理“<”和“>”符号,但是我没有看到你的答案,处理任何代码“|”,那么,您如何甚至它期待工作?现在的问题是你传递“|”作为ls
的一个参数,实际上你应该在管道后面运行这个东西,作为将标准输出ls
发送到该命令的标准输入的命令。
你为什么试图通过手动解析东西和设置管道从头开始创建一个shell?难道你不能只用system()
来执行一个shell命令吗?
难道你不需要知道“|”在你运行ls之前,因为它会运行并发送到标准输出,而不是我想将它发送到下一个命令 –
另外一个要点是将管道集成到其中。我只是在编写代码的时候遇到了麻烦,而不是手动编写管道 –
不,系统()调用的重点在于它使用shell执行命令('/ bin/sh '根据我在我的回答中链接到的文档)。你的shell将解析管道角色并做适当的事情,因为这是shell应该做的主要事情之一。如果这是作业,那么老师是否明确说过你不能使用'system()'或者运行一个像sh或bash这样的外部shell? –
确保你没有任何标签在你的代码copy'n'paste然后缩进。它弄得一团糟。 –
是的,在管道之前或之后处理命令之前,您必须知道管道。你可以调用函数'get_pipe()',但不要在问题中包含该函数。还有其他的缺失功能。这不是一个MCVE([MCVE])。很难知道'get_pipe()'函数的作用。你需要它来分割'ls -l | sort -k2n -k5n | sed's/*// g'| less“分成4组独立的命令加参数,并且管道不会出现在任何参数列表中。 'sed'命令也只需要两个参数,并且没有引号(shell将它们删除)。你可以跳过引用参数的东西。 –