2011-01-15 13 views
1

sshを使ってサーバーとの接続を呼び出すC++アプリケーションがあります。私は時々sshのセッションは、サーバーが終了した召喚のコマンドが終了した後、長い間横たわっていることがわかりました。sshセッションが時々終了しない理由を理解するには?

The session terminates when the command or shell on the remote machine 
exits and all X11 and TCP/IP connections have been closed. The exit 
status of the remote program is returned as the exit status of ssh. 

は、私は、コマンドが終了したことがわかり、私はすべてのX11やTCP/IP接続がクローズされていないと想像します。ssh用Centos4のmanページを見て私は、以下を参照してください。どうすればこれらのsshが待っているのか知ることができます。私の召喚コマンドのC++アプリケーションを修正して、残っているものをクリーンアップしてsshを開いたままにしておくことができます。

なぜこの失敗は時間の一部だけで、すべての呼び出しでは発生しないのだろうか?それは時間の約50%が発生するようです。私のC++アプリケーションはこれを引き起こすために何を残すことができますか?

その他の背景:サーバーはデーモンで、起動するとフォークと親が終了し、子を実行したままになります。使用してクライアントの召喚状:

popen("ssh -n -o ConnectTimeout=300 [email protected] \"sererApp argsHere\"" 
     " 2>&1 < /dev/null", "r") 

答えて

2

使用libssh又はlibssh2、むしろCからpopen(3)を呼び出すよりのみ自体が別のCプログラムであるssh(1)を起動します。私の個人的な経験を望むなら、試してみてください。libssh2 - 私はこれをC++プログラムで使用しています。

+0

今のところ、fork()の子でfclose(stderr)を実行して終了し、sshはもう孤立していません。 – WilliamKF

0

が、私はここにいくつかのヒントを見つける:

http://www.snailbook.com/faq/background-jobs.auto.html

を、この問題は通常、OpenSSHサーバの機能によるものです。 SSHサーバーを作成するときは、「サーバーはいつSSH接続を終了する必要がありますか?」という質問に答える必要があります。明らかな答えは、クライアント要求(シェルまたはリモートコマンド)によって開始されたサーバー側のユーザープログラムが終了したときに閉じます。しかし、実際は少し複雑です。この単純な戦略は、データ損失を引き起こす可能性のある競合状態を許容します(以下の説明を参照)。 この問題を回避するために、sshdはユーザプログラムのstdoutとstderrに接続するパイプ上でend-of-file(eof)を検出するまで待ちます。

+0

これは私のシステムで起こっていることです。マニュアルページが間違っています - プロセスが終了しても終了しません。 "ssh host 'sleep 20&'"でテストできます。問題は、もちろん、あなたのスクリプトがそれほど明白ではないが、おそらくプロセスの背後に(バックグラウンドでさえ)残っている場合です。私はまだその事件の解決策を見いだせなかった。 – sienkiew

0

@sienkiew:実際にsshでコマンドまたはスクリプトを実行して終了したい場合は、libslackパッケージのdaemonツールをご覧ください。 (その標準ストリームからのコマンドを切り離すことができ、同様のツールはscreentmuxまたはdetachだろう。)

標準入力を検査するには、コマンドライン上sshを経由して実行したコマンドの標準出力&標準エラー出力は、次のことができ、例えば、使用lsof

# sample code to figure out why ssh session does not exit 
# sleep keeps its stdout open, so sshd only sees EOF after command completion 
ssh localhost 'sleep 10 &'  # blocks 
ssh localhost 'sleep 10 1>&- &' # does not block 

ssh localhost 'sleep 10 & lsof -p ${!}' 
ssh localhost 'sleep 10 1>&- & lsof -p ${!}' 
ssh localhost 'sleep 10 1>/dev/null & lsof -p ${!}' 
ssh localhost 'sleep 10 1>/dev/null 2>&1 & lsof -p ${!}' 
関連する問題