bash 在 c 中为 shell 创建后台进程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20432595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 08:55:17  来源:igfitidea点击:

Creating a background process for shell in c

clinuxbashshellexec

提问by tyb

Im trying to make my own shell in C, but Im having trouble with handling background and foreground processes. Here is where I create processes:

我试图用 C 制作我自己的 shell,但我在处理后台和前台进程时遇到了麻烦。这是我创建流程的地方:

void call_exec(char *cmd) 
{
pid_t cpid;
is_Background();
if(index(cmd, '/') == NULL) {
    int i;
printf("cmd is %s\n", cmd);
cpid = fork();
if(cpid == 0) {
    i = execvp(cmd, my_argv);
    if(i < 0) {
        printf("%s: %s\n", cmd, "command not found");
        exit(1);        
    }   
} 
else {
    if(!is_BG ) {
        wait(NULL);
    }
    is_BG = 0;
}
}

is_Background:

is_背景:

void is_Background() {
if(strcmp(my_argv[arg_index], "&") == 0) {
    is_BG = 1;
    my_argv[arg_index] = NULL;
}
}

When I run my code and enter "gedit" in command line, shell waits until I close gedit window and then prompts me to enter new command. When I enter "gedit &" to run gedit in the background, it just works fine, gedit window opens and shell immediately prompts me to enter new command without waiting to close gedit window. The problem is, after I use "&" with any command only once, shell never waits for any foreground processes to end/close. Ex, if I enter "gedit" or "firefox" without "&" , shell doesn't wait for them to close.

当我运行代码并在命令行中输入“gedit”时,shell 会等到我关闭 gedit 窗口,然后提示我输入新命令。当我输入“gedit &”在后台运行 gedit 时,它工作正常,gedit 窗口打开,shell 立即提示我输入新命令,而无需等待关闭 gedit 窗口。问题是,在我只对任何命令使用“&”一次后,shell 从不等待任何前台进程结束/关闭。例如,如果我输入没有 "&" 的 "gedit" 或 "firefox" ,shell 不会等待它们关闭。

I hope I was able to explain my problem properly, my English isn't that good, so sorry for mistakes. If I need to provide more information please tell me. Thanks.

我希望我能够正确地解释我的问题,我的英语不是很好,很抱歉有错误。如果我需要提供更多信息,请告诉我。谢谢。

采纳答案by that other guy

There are two issues here:

这里有两个问题:

First of all, gedit and firefox are single instance programs. Any other invocations will just reuse the existing instance. You see the same thing in bash:

首先,gedit 和firefox 是单实例程序。任何其他调用只会重用现有的实例。你在 bash 中看到同样的事情:

bash$ gedit &   # Starts gedit and returns immediately
bash$ gedit     # Opens a new tab in the existing window and returns immediately

You should test with multiple instance programs like xtermor xeyesinstead.

您应该使用多个实例程序进行测试,例如xtermxeyes代替。

Secondly, your wait(NULL)call waits for any process to close, not necessarily the last one. In your shell, you'd probably see this:

其次,您的wait(NULL)调用会等待任何进程关闭,不一定是最后一个。在您的 shell 中,您可能会看到:

yourshell$ xterm &  # starts xterms and returns immediately. 
# Now close the xterm before running the next command
yourshell$ xeyes    # starts xeyes, waits on xterm, returns immediately

You can instead use waitpid(cpid, NULL, 0)to wait for the correct process.

您可以改为使用waitpid(cpid, NULL, 0)等待正确的过程。