首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何同步管道linux中的输入和输出?

如何同步管道linux中的输入和输出?
EN

Stack Overflow用户
提问于 2016-04-27 02:16:44
回答 2查看 1.1K关注 0票数 0

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

这就是我在航站楼上看到的。在SSH到达另一个终端后。我在终点站做了下面的事。

代码语言:javascript
复制
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
# 

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

代码语言:javascript
复制
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时,它似乎可以工作。然而,它变得非常粗俗,我觉得我打字太慢了。系统变得太慢了。另外,我在这个终端上有一个网络服务器。我看到我不能再访问网络了。所以,解决办法是在stdin附近,但我不确定。

代码语言:javascript
复制
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;
    }

基本上,我增加了-关闭(Stdin);

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-27 03:03:02

您有两个不同的进程试图从STDIN读取。这导致过程1得到焦炭1,过程2得到焦炭2,过程1得到焦炭3,进程2得到焦炭4,等等,交替来回。

你的两个过程是:

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

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

票数 1
EN

Stack Overflow用户

发布于 2016-04-27 02:31:29

我最初的想法是,它可能是在缓冲输出:stdout是缓冲的,所以除非您打印换行符,否则在一定数量的字符生成之前,什么都不会打印。这是因为I/O操作很昂贵。您可以在这个here上找到更多的细节。结果是,由于您的程序正在等待打印,因此出现了延迟。

我的建议是:在main函数中,在调用sshLogin函数之前,尝试禁用使用以下代码行的缓冲:

代码语言:javascript
复制
setbuf(stdout, NULL);

您也可以周期性地调用fflush(stdout);来做同样的事情,但是上面的方法更有效。试一试,看看这是否解决了你的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36879124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档