2012-03-29 17 views
7

Capistranoタスク(バックグラウンドでデーモンを起動しようとした)がハングアップした理由を理解した後、&&をssh上のbashで使用すると、バックグラウンド。私はbash 4.1.5と4.2.20で試しました。bash &&演算子がssh上のバックグラウンドを防止する

以下はbashで(すなわち終了するsleepのを待つ)ハングします:

ssh localhost "cd /tmp && nohup sleep 10 >/dev/null 2>&1 &" 

以下はしません:

ssh localhost "cd /tmp ; nohup sleep 10 >/dev/null 2>&1 &" 

どちらこれは以下となります。

cd /tmp && nohup sleep 10 >/dev/null 2>&1 & 

は、 zshとdashの両方とも、&&に関係なく、すべてのケースでバックグラウンドで実行されますとssh。これはbashやバグの通常の/期待される動作ですか?

+1

私は正確にあなたの質問への答えを知っているが、意志はありませんリモートエンドでBashを使用してSSHを使用しているときに時折同じような不具合が発生したとします。問題がBash固有であるかどうかはわかりませんが、 'nohup'コマンドではなく、Bashシェルの' disown'組み込み関数を使用することで、時々運が良くなっています。これに興味があるなら、 'help disown | Bashを実行している間に「少ない」。そして、あなたが一般的な解決策を知りたければ、ここに投稿してください。私は読むことに興味があるはずです。 – thb

+0

私は実際に 'disown'、' nohup'とリダイレクションのさまざまな組み合わせで無益にしようとしました。 '&&'はバックグラウンドを常に禁止します。私はサブシェルで2つのコマンドをラップすることで逃げることができましたが、それは本当に同じことではありません。 – Hinrik

+0

コマンドは私にとってはうまくいくようです。ハングアップはどういう意味ですか? 'cd'は長い時間がかかりますか?これは、リモートサーバーの問題である可能性があります。あまりにも多くの負荷。 – suvayu

答えて

4

一つの簡単な解決策は、使用することです:

ssh localhost "(cd /tmp && nohup sleep 10) >/dev/null 2>&1 &" 

(これはまた、あなたが中括弧を使用している場合、下記の2番目の例を参照してください動作します)。

私は、さらに実験しませんでしたが、私はそれがぶらぶらオープンファイル記述子としなければならない合理的に確信しています。 bashで

{ cd /tmp && nohup sleep 10; } >/dev/null 2>&1 

:これはと綴られなければなら何を意味しているので、おそらくのzshやダッシュは&&をバインドします。


いいえ、ダッシュでの迅速な実験では、 echo foo && echo bar >fileが後者のみをリダイレクトすることが示されています。それでも、オープンなfdが残っているので、sshはより多くの出力を待つことになります。私はこれまで多くのことをやり遂げました。
この特殊なケースでかっこや中かっこを使用する場合はもう1つのトリックは必要ありませんが、より一般的なコンテキストでは &&のコマンドセットがより複雑な場合に便利です。 bashが ;で不適切 &&ではなく、ファイルディスクリプタにぶら下がっているように見えるので、あなたは a || exit 1; b || exit 1; ca && b && cを変えることができます。これは、テストケースで動作します:

ssh localhost "true || exit 1; echo going on; nohup sleep 10 >/dev/null 2>&1 &" 

falsetrueを交換し、「上に行く」の反響が省略されています。

(。あなたがすることもできset -e、時にはそれが所望のものよりも大きいハンマーですが)

+0

ええ、 '&& 'を' || exit 1; 'は使用する回避策です。 – Hinrik

1

これは動作するようです:

ssh localhost "(exec 0>&- ; exec 1>&-; exec 2>&-; cd /tmp; sleep 20&)" 
+1

すべてのディスクリプタを先に閉じるという欠点は、エラーメッセージを元の( 'ssh')ホストに返すことができないことです。 – torek