linux - 如何在管道 linux 中同步输入和输出?

标签 linux pipe fork

我正在从自定义 shell 创建一个 shell 命令,以执行从一个终端到另一个终端的 ssh。 为了执行 ssh,我使用了 linux 的内置 ssh 命令。这是我执行 ssh 登录的代码。 但是,我发现 I/O 缓冲区不同步。

这是我在终端上看到的。 SSH 到另一个终端后。我在终端中执行了以下操作。

PRT# ssh 192.168.10.42
PRT# Could not create directory '/root/.ssh'.
root@192.168.10.42's password: 
# screen -r
-sh: cen-: not found
# hello
-sh: el: not found
# 

我不知道这是什么原因。这是代码。

int sshLogin(chr *destIp)
{
    char cmd[CMD_LEN];
    char readbuff[CMD_LEN];
    pid_t pid;
    int ret = 0;
    int fd[2];
    int result;
    memset(cmd,'\0',sizeof(cmd));
    int status = 0;

    /** --tt required to force pseudowire allocation because we are behind screen app **/
    sprintf(cmd,"/usr/bin/ssh -tt %s",destIp);

    /** create a pipe this will be shared on fork() **/
    pipe(fd);

    if((pid = fork()) == -1)
    {
        perror("fork:");
        return -1;
    }
    if( pid == 0 )
    {
        /** Child Process of Main APP --Make this parent process for the command**/

        if((pid = fork()) == -1)
        {
            perror("fork:");
            return -1;
        }

        if( pid == 0)
        {
            /** basically Main APP grand child - this is where we running the command **/
            ret = execlp("ssh", "ssh", "-tt", destIp, NULL);
            printf("done execlp\r\n");
        }
        else
        {
           /** child of Main APP -- keep this blocked until the Main APP grand child is done with the job **/
            while( (read(fd[0], readbuff, sizeof(readbuff))))
            {
                printf("%s",readbuff);
            }

            waitpid(0,&status,0);
            LOG_STRING("SSH CONNC CLOSED");
            exit(0);
        }
    }
    else
    {
        /** Parent process APP MAIN--  **/
        /** no need to wait let APP MAIN run -- **/
    }

    return 0;
}

基于帕特里克的想法。

POST 2# - 它似乎在我们关闭父进程中的标准输入时起作用。但是,它变得非常迟钝,我觉得我在键盘上打字太慢了。系统变得太迟钝了。另外,我有一个来自这个终端的网络服务器。我发现我无法再访问网络。 所以,解决方案就在 stdin 附近,但我不确定。

int sshLogin(chr *destIp)
    {
        char cmd[CMD_LEN];
        char readbuff[CMD_LEN];
        pid_t pid;
        int ret = 0;
        int fd[2];
        int result;
        memset(cmd,'\0',sizeof(cmd));
        int status = 0;

        /** --tt required to force pseudowire allocation because we are behind screen app **/
        sprintf(cmd,"/usr/bin/ssh -tt %s",destIp);

        /** create a pipe this will be shared on fork() **/
        pipe(fd);

        if((pid = fork()) == -1)
        {
            perror("fork:");
            return -1;
        }
        if( pid == 0 )
        {
            /** Child Process of Main APP --Make this parent process for the command**/

            if((pid = fork()) == -1)
            {
                perror("fork:");
                return -1;
            }

            if( pid == 0)
            {
                /** basically Main APP grand child - this is where we running the command **/
                ret = execlp("ssh", "ssh", "-tt", destIp, NULL);
                printf("done execlp\r\n");
            }
            else
            {
               /** child of Main APP -- keep this blocked until the Main APP grand child is done with the job **/
                while( (read(fd[0], readbuff, sizeof(readbuff))))
                {
                    printf("%s",readbuff);
                }

                waitpid(0,&status,0);
                LOG_STRING("SSH CONNC CLOSED");
                exit(0);
            }
        }
        else
        {
            /** Parent process APP MAIN--  **/
            /** no need to wait let APP MAIN run -- **/
            close(stdin);
        }

        return 0;
    }

基本上,我添加了 - close(stdin);

最佳答案

您有 2 个不同的进程试图从 STDIN 读取数据。这导致进程 1 获取 char 1,进程 2 获取 char 2,进程 1 获取 char 3,进程 2 获取 char 4,等等,来回交替。

您的 2 个进程是:

  1. execlp("ssh", "ssh", "-tt", destIp, NULL);
  2. while( (read(fd[0], readbuff, sizeof(readbuff))))

基本上你需要放弃 read(fd[0],...)

关于linux - 如何在管道 linux 中同步输入和输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36879124/

相关文章:

linux - 创建本地 git 存储库失败

linux - 有没有办法检查 zip 文件是否受密码保护?

perl - 使用具有多个管道进程的 Perl system() 检测错误

bash - 如何在使用 silent 标志时使 curl 请求的 HEAD 静音?

c - 使用 Fork() 将整数传递给子进程和父进程的 Linux 系统调用问题

perl - 为什么 "fork inside BEGIN ... a horrible prospect"在 Perl 中?

linux - 在线替换 bash(使用变量将行替换为新行)

linux - linux 无法添加环境变量

linux - 使用 PV 计算行数并显示总行数而不是管道中的总字节数

c - Unix 系统调用按升序然后降序打印数字