- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在我的操作系统签名中用 c 语言制作了一个 UNIX minishell。我只需要改进 shell 本身,我们有一个用于实现 yacc 的预制解析器和一个用于在其他文件中实现 lex 的扫描器。要修改的文件是主执行文件msh.c。
好吧,当我尝试实现管道序列时,问题就开始了。这是我做的:
int executePipeLine (char*** argvv, int bg, char** filev, int n){
int i;
int in = 0;
pid_t pid;
int fd[2];
for (i = 0 ; i < n-1 ; i++){
pipe(fd);
pid_t pid = fork();
if (pid == 0){ //child
if (in != STDIN_FILENO){
dup2(in, STDIN_FILENO);
close(in);
}
if (fd[1] != STDOUT_FILENO){
dup2(fd[1], STDOUT_FILENO);
close(fd[1]);
}
execvp(argvv[i][0], argvv[0]);
}
else { //parent
close(fd[1]);
in = fd[0];
}
}
if(in != STDIN_FILENO){
dup2(in, STDIN_FILENO);
close(in);
}
pid_t lastpid = fork();
if(lastpid == 0){ //child
execvp(argvv[i][0], argvv[0]);
}
if(lastpid == -1){
perror("no se pudo crear el hijo\n");
exit(-1);
}
else { //parent
/* not bg*/
if(!bg ) {
int status;
while (wait(&status) != lastpid); /* wait the child. */
}
else {
/*bg mode*/
printf("pid del proceso last: %d\n", lastpid);
}
return 0;
}
}//end executePipeLine
这似乎工作正常。在 main 中,我们有一个名为 obtain_order() 的外部函数;返回命令数 + 1 并将其保存到 ret。如果 ret 为 1,我们继续提示,如果为 0,则表示 EOF(Control + D 键绑定(bind))结束 shell,如果为 >1,则执行命令。
给你:
int main(void)
{
char ***argvv;
int command_counter;
int num_commands;
int args_counter;
char *filev[3];
int bg;
int ret;
int reset = 0;
setbuf(stdout, NULL); /* Unbuffered */
setbuf(stdin, NULL);
while (1)
{
fprintf(stderr, "%s", "msh> "); /* Prompt */
ret = obtain_order(&argvv, filev, &bg);
printf("ret: %d\n", ret);
if (ret == 0) break; /* EOF */
if (ret == -1) continue; /* Syntax error */
num_commands = ret - 1; /* Line */
if (num_commands == 0) continue; /* Empty line */
if(num_commands > 1){
executePipeLine(argvv, bg, filev, num_commands);
}
else if (num_commands == 1){
executeCommand(argvv, bg, filev);
}
} //fin while
return 0;
} //end main
通过一个简单的命令一切正常。问题是当我尝试执行管道时。它显示了一个很好的结果,但我不知道我们,在下一次迭代中 ret 总是为 0,所以每次我尝试执行管道时,它都有效但关闭 shell 进程,并且必须再次执行它而不是继续提示。
你知道这里的问题是什么吗?
我希望你能理解我,我的英语并不完美。谢谢
最佳答案
在父进程(即您的迷你 shell)中,您正在dup
标准输入:
...
else { //parent
close(fd[1]);
in = fd[0];
}
...
if(in != STDIN_FILENO){
dup2(in, STDIN_FILENO);
close(in);
}
当你的管道终止时, children 死了,管道不再可读=> stdin 被认为是关闭的。当您稍后在主循环中调用 obtain_order
时,它返回 0 (EOF) 并且您的程序退出。
关于c - 在 c 中创建的 minishell 无法按预期工作,与管道相关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43081712/
所以我正在用 C(用于 unix)构建一个 minishell。我只是想出了如何让管道工作,但是我遇到了僵尸问题。假设我有: echo a | echo b | echo c 这不输出任何东西,当它应
我正在用 C 语言编写一个 unix minishell,并且正在添加命令扩展。我的意思是我可以将命令嵌套在其他命令中,例如: $> echo hello $(echo world! ... $(ec
我正在编写一个迷你 shell 程序。它给了我“args = my_str2vect(line);”行中的段错误。不过,“my_str2vect”函数以及 my_strncpy 函数和 my_strl
我实际上正在尝试用 C 实现一个基本的 minishell。为此,我制作了一个函数来解析用户在控制台中输入的内容。我解析了它,然后我想使用管道将命令发送到控制台。我不明白为什么我的管道不工作。我检查了
嗨,我最近开始学习unix系统编程。 我正在尝试用 c 创建一个 minishell,但是当我运行我的代码时, 我总是得到: EXC_BAD_ACCESS (code=EXC_I386_GPFLT 不
基本上我想做的是: 如果我写 Hello I am here char command[20] 应该是 'Hello'(那部分有效)并且 char *parameters 应该有指向 ' 你好' '我
我用 C 做了一个简单的 minishell,它可以工作,除了 cd 命令。当我尝试运行它时,除了它创建了一个永远不会真正结束的子进程之外,什么也没有发生。例如,在我的 minishell 中运行 c
我正在尝试编写一个内置功能非常有限的 minishell。但是,现在每当我处理 SIGINT 时,我都必须再次按回车键才能输入更多命令。 void loop() { struct sigact
我正在用 C 语言制作一个 minishell,我正在考虑环境变量。我从用户那里获取原始输入行,并将其传递给一个函数: int expand(char *orig, char *new, int ne
我在我的操作系统签名中用 c 语言制作了一个 UNIX minishell。我只需要改进 shell 本身,我们有一个用于实现 yacc 的预制解析器和一个用于在其他文件中实现 lex 的扫描器。要修
我正在尝试用这段代码编写一个 minishell: #include #include #include #define LINE_LEN 50 #define MAX_PARTS 50 i
这个问题在这里已经有了答案: Is it possible to distinguish the error returned by fgets (2 个答案) 关闭 2 年前。 我写了这个 min
我是一名优秀的程序员,十分优秀!