如何为每个子进程bash分配一个新的终端窗口

问题描述 投票:2回答:2

我想分叉多个进程并为每个子进程分配它自己的终端窗口,以便可以轻松演示IPC。分叉很顺利,如果我在同一个终端上运行子进程,它运行正常。但是为了让每个子进程都有自己的终端窗口,我这样做

execl("/usr/bin/xterm", "xterm", "-e", "yourprogram", NULL);

该程序在一个新窗口中运行,但其PID不同于父进程显示的PID。我究竟做错了什么?

谢谢

edit1 - 这是我的主要功能(父进程)。我分叉了4个子进程。我希望每个子进程都有自己的终端窗口。然而,子进程刚退出,并且具有不同PID的新进程继续在新终端中运行。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main()
{

pid_t pid[4]; 
int i = 0;
int status;

//Fork four new processes
for(i=0; i<4; i++)
{
    pid[i] = fork();

    if(pid[i] == 0 && i == 0)
    {
        execl("/usr/bin/xterm", "xterm", "./child1", NULL);
        exit(1);
    }
    else if(pid[i] == 0 && i == 1)
    {
        execl("/usr/bin/xterm", "xterm", "./child2", NULL);
        exit(1);
    }
    else if(pid[i] == 0 && i == 2)
    {
        execl("/usr/bin/xterm", "xterm", "./child3", NULL);
        exit(1);
    }
    else if(pid[i] == 0 && i == 3)
    {
        execl("/usr/bin/xterm", "xterm", "./child4", NULL);
        exit(1);
    }
    else
    {
        //Parent process
        printf("The main function has forked a process with pid: %d\n", pid[i]);
    }
}

for(i=0;i<4;i++)
{
    status = waitpid(pid[i], NULL, 0);
    if(status == pid[i])
        printf("%d: Process Terminated Successfully\n", pid[i]);
    else
    {
        perror("waitpid");
        exit(1);
    }
}

return 1;
}

edit2 - 添加了ps -u输出:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
dell-pc   3024  0.1  0.0  26872  5480 pts/0    Ss   16:54   0:00 bash
dell-pc   3038  0.0  0.0   4200   632 pts/0    S+   16:54   0:00 ./main
dell-pc   3039 22.5  0.1 109240 11116 pts/0    S+   16:54   0:01 xterm ./child1
dell-pc   3040 26.1  0.1 109240 11268 pts/0    R+   16:54   0:02 xterm ./child2
dell-pc   3041 28.7  0.1 109240 11180 pts/0    S+   16:54   0:02 xterm ./child3
dell-pc   3042 27.0  0.1 109240 11288 pts/0    S+   16:54   0:02 xterm ./child4
dell-pc   3044  4.1  0.0   4200   648 pts/24   Ss+  16:55   0:00 child3
dell-pc   3046  3.7  0.0   4200   680 pts/26   Ss+  16:55   0:00 child4
dell-pc   3048  3.8  0.0   4200   792 pts/25   Ss+  16:55   0:00 child2
dell-pc   3050  3.3  0.0   4200   660 pts/14   Ss+  16:55   0:00 child1
dell-pc   3060  2.0  0.0  26816  5412 pts/27   Ss   16:55   0:00 bash
dell-pc   3072  0.0  0.0  22648  2688 pts/27   R+   16:55   0:00 ps -u

edit3:添加了main的输出:

The main function has forked a process with pid: 3491
The main function has forked a process with pid: 3492
The main function has forked a process with pid: 3493
The main function has forked a process with pid: 3494
3491: Process Terminated Successfully
3492: Process Terminated Successfully
3493: Process Terminated Successfully
3494: Process Terminated Successfully
c linux fork exec ipc
2个回答
1
投票

我做了一个类似你的程序(命名为stackoverflow),在xterm中执行vi,当它运行时我打开第三个xterm来运行ps -u。输出是:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
osboxes   1713  0.0  0.2   6588  4756 pts/0    Ss   18:56   0:00 bash
osboxes   1780  0.0  0.2   6508  4484 pts/1    Ss   19:12   0:00 bash
osboxes   1836 88.4  0.0   2020   532 pts/0    R+   19:21   0:29 ./stackoverflow
osboxes   1837  0.1  0.4  12844  8952 pts/0    S+   19:21   0:00 /usr/bin/xterm -e vi stackoverflow.txt
osboxes   1839  0.0  0.1   6072  3536 pts/2    Ss+  19:21   0:00 vi stackoverflow.txt
osboxes   1840  0.0  0.1   4772  2452 pts/1    R+   19:22   0:00 ps -u

计划的输出是:

PID=1836
child PID=1837

所以孩子仍在运行xtermcommand。它创造了另一个运行vi的孩子(pid 1839)。


1
投票

IPC Demo and sample using terminal windows, under

因为在下很容易:

这将需要简单的终端工具,如xterm。这是用lxtermmate-terminalkonsolegnome-terminal成功测试的。当然,tmuxscreen也必须能够......

好的,我们走吧。我们假设您已经在某个终端窗口,我们将命名这个初始控制台。

1.首先打开一个显示窗口:

所以,从初始控制台,打开日志窗口:

exec 5> >(xterm -T 'Log window...' -e sh -c "cat /proc/$$/fd/5")

要么

exec 5> >(xterm -e sh -c "printf '\\e];Log window...\\a';cat /proc/$$/fd/5")

exec 5> >(konsole --nofork -e sh -c "cat /proc/$$/fd/5")
exec 5> >(lxterm -T "Log window..." -e sh -c "cat /proc/$$/fd/5")
exec 5> >(mate-terminal -t 'Log window...' -x sh -c "cat /proc/$$/fd/5")
exec 5> >(gnome-terminal --window -x sh -c "printf '\\e];Log window...\\a';cat /proc/$$/fd/5")

Variant usefull for debugging

exec 5> >(xterm -e sh -c "printf '\\e];Log window...\\a';
              tee </proc/$$/fd/5 /dev/tty | sed -u s/.*/now/|date -f -")

将在每行输出上打印日期和时间。

exec 5> >(xterm -e sh -c "printf '\\e];Log window...\\a';
              tee </proc/$$/fd/5 /dev/tty | sed -u s/.*/now/|date -f - ; read foo")

相同,但在关闭之后将保持窗口打开,在关闭之前等待终端输入(返回)(或由窗口管理器关闭)。

2.测试,然后使用:

始终在初始控制台中,点击:

echo >&5 This is a test string.

这必须在日志窗口中提示。

现在可以:

xterm -T 'Input window' -e bash --rcfile <(echo "exec 1>/proc/$$/fd/5") &

注意:在那里,双引号将确保$$将从初始窗口的shell级别扩展。

现在,您可以在输入窗口中输入命令并在日志窗口中读取结果。

3.关闭窗口

关闭文件描述符时窗口将关闭:

exec 5>&-

完整脚本使用3窗口

您可以在那里找到完整的脚本:

© www.soinside.com 2019 - 2024. All rights reserved.