首页 > 解决方案 > 当 shell 读取命令时,有什么方法可以防止后台进程写入 stdout 通道?

问题描述

我正在用 C 编写一个 shell。shell 有内部和外部命令。外部命令可以使用与号 (&) 进行扩展,以便它们在后台运行。

当我输入 egprogram&时,program后台执行没有问题,在程序执行时使 shell 可用。

但是,输出program可以与 shell 的正常输出混合。这就是我试图解决的问题,但没有成功。

注意:在上面的示例中,我谈到了program任何其他命令。program基本上睡觉,然后打印“Hello,World!” 。此外,“程序”在 /bin/ 中,这是我的外部命令的默认目录。


sish> pwd
[current directory]
sish> program&
sish> [now if I don't type anything...] Hello, World!
[now the current command is being written here].

例如,在 bash 中,这种行为就不同了,看起来,如果用户“还在”写命令,那么后台程序的输出正在等待(或等待),因此用户可以执行程序。因此,不要弄乱输出。

我读了一些关于信号的信息,我尝试设置一个信号处理程序,在 SIGCHLD 上打印一些东西,但它也有相同的行为。

代码:

while(1) {
        int internal=0;
        int background=0;
        int redirect=0; // 1 - output ; 2 - input
                // those variables are not important for the question

        printf("sish> ");
        fgets(command,BUFFER_SIZE,stdin);
}

...(一些对问题不重要的行)

            child = fork(); // pid_t child -> global variable
            if(!child) {

                if(redirect==1) { 

                    int fd = open(words[2],O_WRONLY|O_CREAT|O_TRUNC,0660);
                    dup2(fd,1);
                    execlp(words[0],words[0],NULL);
                }

                else if(redirect==2) {

                    int fd = open(words[2],O_RDWR);
                    dup2(fd,0);
                    execlp(words[0],words[0],NULL);
                }

                else {

                    if(execvp(bin_path,words)==-1) {
                        printf("Error! Does the program exist?\n");
                    }
                }
            }

注意: - 我知道我没有检查分叉中的错误,我会在解决此错误时添加。- 我还用 打印了 STDERR perror,我什么都没有。

我期望这个(例如):

sish> pwd
[current directory]
sish> program&
sish> [I wait...] pwd
[current directory]
Hello, World!

标签: cshellunix

解决方案


推荐阅读