- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编写了一个C程序,它使用多个管道来模拟shell。问题是我可以运行大多数命令,例如 ls | cat
等,但我无法使用 ls |厕所。是否存在 wc
不起作用的情况?
int pipefd[4];
int p1 = pipe(pipefd); // Open pipe 1
int p2 = pipe(pipefd + 2); // Open pipe 2
pid_t pid;
for(i = 0; i < n_commands; i++)
{
fflush(stdout);
pid = fork();
if(pid == 0)
{
int command_no = i;
int prev_pipe = ((command_no - 1) % 2) * 2;
int current_pipe = (command_no % 2) * 2;
// If current command is the first command, close the
// read end, else read from the last command's pipe
if(command_no == 0)
{
close(pipefd[0]);
}
else
{
dup2(pipefd[prev_pipe], 0);
close(pipefd[current_pipe]);
}
// If current command is the last command, close the
// write end, else write to the pipe
if(command_no == n_commands - 1)
{
close(pipefd[current_pipe + 1]);
}
else
{
dup2(pipefd[current_pipe + 1], 1);
}
int p = execvp(tokens[cmd_pos[command_no]], tokens + cmd_pos[command_no]);
close(pipefd[current_pipe]);
close(pipefd[prev_pipe]);
close(pipefd[prev_pipe + 1]);
close(pipefd[current_pipe + 1]);
_exit(0);
}
}
如果 /usr/bin
中的程序不是管道中的第一个命令,则它们似乎不会被执行。
最佳答案
这是一个根据您的代码创建的非常简单的程序 - 猜测如何创建管道并稍微简化命令 argv
处理:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static char *argv_ls[] = { "ls", 0 };
static char *argv_wc[] = { "wc", 0 };
static char **cmds[] = { argv_ls, argv_wc };
int main(void)
{
int n_commands = 2;
int pipefd[2];
pipe(&pipefd[0]); // Error check!
fflush(stdout);
for (int i = 0; i < n_commands; i++)
{
int pid = fork();
if (pid == 0)
{
int command_no = i;
int prev_pipe = ((command_no - 1) % 2) * 2;
int current_pipe = (command_no % 2) * 2;
printf("cmd %d: prev pipe %d, curr pipe %d\n", i, prev_pipe, current_pipe);
fflush(stdout);
// If current command is the first command, close the
// read end, else read from the last command's pipe
if (command_no == 0)
{
close(pipefd[0]);
}
else
{
dup2(pipefd[prev_pipe], 0);
close(pipefd[current_pipe]); // Line 40
}
// If current command is the last command, close the
// write end, else write to the pipe
if (command_no == n_commands - 1)
close(pipefd[current_pipe + 1]); // Line 46
else
dup2(pipefd[current_pipe + 1], 1);
execvp(cmds[i][0], cmds[i]);
fprintf(stderr, "Failed to exec: %s (%d: %s)\n", cmds[i][0], errno, strerror(errno));
_exit(1);
}
}
return 0;
}
当 GCC 4.7.1(在 Mac OS X 10.7.4 上)编译它时,它会发出警告:
pipes-12133858.c: In function ‘main’:
pipes-12133858.c:40:22: warning: array subscript is above array bounds [-Warray-bounds]
pipes-12133858.c:46:22: warning: array subscript is above array bounds [-Warray-bounds]
当我运行它时,我得到输出:
Isis JL: pipes-12133858
cmd 0: prev pipe -2, curr pipe 0
cmd 1: prev pipe 0, curr pipe 2
Isis JL: wc: stdin: read: Bad file descriptor
由于代码中的父级不等待子级完成,因此在来自 wc
的错误消息之前会出现提示,但打印的诊断号显示存在各种问题(并且编译器能够发现一些问题)。
请注意,无需检查任何 exec*()
系列函数的返回值。如果他们成功了,他们就不会回来;如果他们成功了,他们就不会回来。如果他们回来,他们就失败了。在调用 _exit(0);
之前也不需要关闭,因为系统无论如何都会关闭它们。此外,当您无法执行某些操作时,有礼貌的是打印一条消息来指示您无法执行的操作并以非零退出状态退出。
所以,如Michał Górny说,你的问题的一个主要部分是你的管道处理代码至少是神秘的,因为你没有显示它并且可能是错误的。
我还可以肯定您的代码中没有足够的 close()
调用。作为指导,在每个打开管道且将成为管道一部分的进程中,由 pipe()
系统调用返回的所有文件描述符应在任何给定子进程之前关闭使用 exec*()
函数。不关闭管道可能会导致进程挂起,因为管道的写入端是打开的。如果写入端打开的进程正在尝试从管道的读取端读取数据,那么它将找不到任何要读取的数据。
关于c - LS |使用 C 的 wc 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12133858/
如果我执行 ls -la,我会得到如下结果 total 16 drwxr-xr-x 4 rockse staff 136 Apr 28 16:55 . drwx------+ 23 rocks
我找到了一些Linux文件,当我键入ls -lah时,它将输出以下权限格式: ... drwxr-xr-x. 2 root root ... -rw-rw-r--. 1 root r
我正在尝试从 python 执行 ls -l 来检查文件的最后修改日期。 os.listdir 不显示长列表格式。subprocess.call 显示格式,但实际上打印它,并返回 0。我希望能够将其放
以下 shell 函数定义卡在 Cygwin 的 bash 控制台 (RHEL/Ubuntu) 中,当它被调用时它只是退出终端。 $ function ls { ls; } $ ls 为什么会出现这种
为什么这两个命令的输出不同: ls | cat ls 第一个似乎用换行符分隔文件名。 这也适用于命令 suc 有 ls > outfile 和类似的东西。 我使用的是 Mac OSX,如果这有什么不同
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我使用 eshell-parse-command 'ls -l' 得到了这个: (progn (eshell-trap-errors (eshell-named-command "l
如何使用 RegExp 在 JavaScript 中实现类似于 alias 的功能? ALIAS = [{pattern: /^ls[$ ]/, replace: 'ls --color '}] s
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我正在编写一个 shell 程序,当将值传递给 execv() 时,我需要一个指向程序名称的 char 指针(即 ls),我需要一个指向参数的 char 指针数组的指针。 我会检查并解析用户的输入,如
我对使用 bash 编写脚本还比较陌生,并编写了以下脚本: # Set variables logfile=/tmp/peter/logfile.log indir=/mls/indir/IG/ te
所以基本上我有一个任务要使用 strace 进行分析,ls 命令需要哪些系统调用才能提供与 ls -l 相同的信息。 但是对于 ls -l 命令有许多奇怪的系统调用,例如 stat 64 被调用时使用
我在 ubuntu 的文件夹中有一个文件夹列表。IE。/mnt/source/customcode/files/brands/下 root@a919794ec280:/mnt/source/custo
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
#include #include #include #include #include int flag; void catch (int sig) { if (sig == SIGI
我使用 Process 来调用 shell(zsh),我想 cd ~ 或其他一些目录,例如在 shell 中定义的 cd $PROJ_ROOT。但似乎无法处理这些 token 。如何解决这个问题? s
我在我的 Centos5 机器上运行了这个: ls -al & ; ls -al 我期待它在后台运行 ls -al,同时在前台运行 ls -al,并演示终端的输出是如何被破坏的通过这样做。 但是,我得
当我在 PowerShell 中使用 Get-ChildItem 时,我会得到目录中以行格式设置的项目列表。该列表经常会超出屏幕,如果我想查看列表的其余部分或以前的命令和输出,则迫使我向上滚动。我想为
我试图用所有必要的参数绕过调用 JNIEnv->DefineClass 方法,但当我尝试从 java 调用该方法时,它总是返回 java.lang.NoClassDefFoundError: ls.H
我是一名优秀的程序员,十分优秀!