2016-04-27 16 views
0

カスタムシェルからシェルコマンドを作成して、ある端末から別の端末にsshを実行します。 sshを実行するために、私はlinuxのinbuilt sshコマンドを使用しています。ここにsshログインを行う私のコードがあります。 しかし、I/Oバッファが同期していないのが見えています。パイプlinuxの入出力を同期させる方法は?

これは私が端末で見ているものです。 SSHの後にもう一方の端末に。私は端末で次のことをしました。

PRT# ssh 192.168.10.42 
PRT# Could not create directory '/root/.ssh'. 
[email protected]'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# - 親プロセスで標準入力を閉じると動作するようです。しかし、それは非常に鈍い、私はキーボードを入力するように遅すぎるように感じる。システムが低速すぎる。また、私はこの端末からWebサーバーを持っています。私はもはやウェブにアクセスすることができないことがわかります。 解決策は標準入力のまわりですが、わかりません。

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);を追加しました。

答えて

1

STDINから読み取ろうとするプロセスが2つあります。これにより、プロセス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],...)を捨てる必要があります。

+0

私は読むことが決して呼ばれないことを見る、実際に、私はその部分を今コメントした。 –

+0

ああ、あなたはフォークされたプロセスが終了するのを待たずにプログラムから戻ってきているので、あなたの親シェルはSTDINとforkした 'ssh'から読み込もうとしている。 – Patrick

+0

は今問題を改訂しました。それはSTDINとだけ関係しているようです。 –

0

私の初期の考えは、おそらく出力をバッファリングしているということです:stdoutはバッファされているので、改行を印刷しない限り、特定の文字数が蓄積されるまで何も印刷されません。これは、I/O操作が高価であるためです。この詳細については、hereをご覧ください。その結果、プログラムが印刷を待機しているために遅延が発生します。

私の提案:あなたのmain機能で、あなたのsshLogin関数を呼び出す前に、このコード行をバッファリングを無効にしてみてください:

setbuf(stdout, NULL); 

あなたも同じことを行うために、定期的にfflush(stdout);を呼び出すことができますが、上記の方法より効率的です。それを試して、それがあなたの問題を解決するかどうかを見てください。

+0

は役に立ちませんでした。私は同じ問題を抱えています。 –

関連する問題