我正在用C语言开发自己的小Shell程序。当将子进程作为后台进程运行时,我想忽略来自父进程的用户输入。我当前正在尝试通过管道将其关闭,然后为孩子关闭stdin,但输入仍将输入给孩子。
else // A process
{
pid_t child_pid;
char lastArgument = args[currArgsIndex-1][0];
if (lastArgument != '&'){ //Normal process
if((child_pid = fork()) == 0) {
execvp(filepath, args);
exit(0);
}
else
{
while(wait(NULL) != child_pid);
}
}
else { // Background
args[currArgsIndex-1] = NULL;
int process_pipe[2];
pipe(process_pipe); // Piping
if((child_pid = fork()) == 0) {
close(process_pipe[0]); // Ignore stdin for child
execvp(filepath, args);
exit(0);
}
}
}
您创建了一个管道并关闭了读取端,但是您从未说过管道应该是标准输入。
听起来您的意图是改为1.仅在子级中打开管道,2.关闭write
端,3.将read
端设置为stdin:
else { // Background
args[currArgsIndex-1] = NULL;
if((child_pid = fork()) == 0) {
int process_pipe[2];
pipe(process_pipe); // Piping
dup2(process_pipe[0], 0); // Copy read end as stdin
close(process_pipe[0]); // Close FD that is now unused
close(process_pipe[1]); // Close write end so no data can be read
execvp(filepath, args);
perror("execvp failed");
exit(1); // exit with error
}
}
虽然没有管道是没有意义的。您可以更轻松地打开/dev/null
进行读取并将其设置为标准输入。或者,只需完全关闭stdin
(一些程序会抱怨):
else { // Background
args[currArgsIndex-1] = NULL;
if((child_pid = fork()) == 0) {
close(0); // Close stdin
execvp(filepath, args);
/* error handling */
}