338

これは、シェル スクリプトで ssh をどのように使用しますか?の続きの質問です。質問。リモート マシンのバックグラウンドで実行されているコマンドをリモート マシンで実行したい場合、ssh コマンドを返すにはどうすればよいですか? コマンドの最後にアンパサンド (&) を含めようとすると、ハングします。コマンドの正確な形式は次のようになります。

ssh user@target "cd /some/directory; program-to-execute &"

何か案は?注意すべきことの 1 つは、ターゲット マシンにログインすると常にテキスト バナーが生成され、 SSHキーが設定されているため、パスワードは必要ありません。

4

17 に答える 17

352

私は1年前に書いたプログラムでこの問題を抱えていましたが、答えはかなり複雑であることがわかりました。ウィキペディアのnohupの記事で説明されているように、nohupと出力リダイレクトを使用する必要があります。これは、便宜上ここにコピーされています。

バックグラウンドジョブは、競合状態が原因でシェルがログアウト時にハングする可能性があるため、SSH経由でログインする場合などに便利です[2]。この問題は、3つのI/Oストリームすべてをリダイレクトすることでも解決できます。

nohup myprogram > foo.out 2> foo.err < /dev/null &
于 2008-08-26T23:18:41.147 に答える
271

これは私にとって最もクリーンな方法です:-

ssh -n -f user@host "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"

この後に実行されるのは、リモート マシン上の実際のコマンドだけです。

于 2010-05-14T02:11:16.513 に答える
38

fd をリダイレクトする

出力をリダイレクトする必要があります。&>/dev/nullこれは、stderr と stdout の両方を /dev/null にリダイレクトし、>/dev/null 2>/dev/nullまたはのシノニムです>/dev/null 2>&1

括弧

最良の方法は、sh -c '( ( command ) & )'where command is anything を使用することです。

ssh askapache 'sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

ノハップ シェル

nohup を直接使用してシェルを起動することもできます。

ssh askapache 'nohup sh -c "( ( chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

素敵な打ち上げ

もう 1 つのトリックは、nice を使用してコマンド/シェルを起動することです。

ssh askapache 'nice -n 19 sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
于 2012-03-17T08:09:14.773 に答える
26

接続を開いたままにしない/できない場合は、インストールする権利があればscreenを使用できます。

user@localhost $ screen -t remote-command
user@localhost $ ssh user@target # now inside of a screen session
user@remotehost $ cd /some/directory; program-to-execute &

screen セッションを切り離すには:ctrl-a d

画面セッションを一覧表示するには:

screen -ls

セッションを再接続するには:

screen -d -r remote-command

screen は、各セッション内で複数のシェルを作成することもできることに注意してください。tmuxでも同様の効果が得られます。

user@localhost $ tmux
user@localhost $ ssh user@target # now inside of a tmux session
user@remotehost $ cd /some/directory; program-to-execute &

tmux セッションを切り離すには:ctrl-b d

画面セッションを一覧表示するには:

tmux list-sessions

セッションを再接続するには:

tmux attach <session number>

デフォルトの tmux コントロール キー ' ctrl-b' はやや使いにくいですが、tmux に同梱されているいくつかのサンプル tmux 構成を試すことができます。

于 2008-08-27T17:00:48.940 に答える
18

カットアンドペーストできる実際の例を示したかっただけです。

ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /dev/null &\""
于 2012-09-05T19:50:27.570 に答える
8

必要なものを得るには、これらの回答のいくつかを組み合わせる必要があると思います。nohup をセミコロンと組み合わせて使用​​し、全体を引用符で囲むと、次のようになります。

ssh user@target "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"

これは私にとってはうまくいくようです。nohup では、実行するコマンドに & を追加する必要はありません。また、コマンドの出力を読み取る必要がない場合は、次を使用できます

ssh user@target "cd /some/directory; nohup myprogram > /dev/null 2>&1"

すべての出力を /dev/null にリダイレクトします。

于 2008-09-11T14:34:14.843 に答える
8

最も簡単で簡単な方法は、「at」コマンドを使用することです。

ssh user@target "at now -f /home/foo.sh"
于 2014-07-11T11:19:10.233 に答える
6

これは私にとって何度もうまくいきました:

ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & " 
于 2013-07-25T16:01:01.470 に答える
6

nohupなしでこれを行うことができます:

ssh user@host 'myprogram >out.log 2>err.log &'
于 2020-02-27T16:19:16.833 に答える
0

私は同じことをやろうとしていましたが、Java からやろうとしていたために複雑さが増しました。したがって、Javaを実行している1台のマシンで、バックグラウンドで(nohupを使用して)別のマシンでスクリプトを実行しようとしていました。

コマンドラインから、これがうまくいきました:(ホストにsshする必要がない場合は、「-i keyFile」は必要ないかもしれません)

ssh -i keyFile user@host bash -c "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\""

私のコマンド ラインでは、「-c」の後に 1 つの引数があり、すべて引用符で囲まれていることに注意してください。しかし、それが反対側で機能するには、引用符が必要なため、エスケープされた引用符をその中に入れなければなりませんでした。

Javaから、これがうまくいきました:

ProcessBuilder b = new ProcessBuilder("ssh", "-i", "keyFile", "bash", "-c",
 "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\"");
Process process = b.start();
// then read from process.getInputStream() and close it.

これを機能させるには少し試行錯誤が必要でしたが、今ではうまく機能しているようです。

于 2010-12-30T21:36:27.513 に答える
0

zsh を使用している場合program-to-execute &!は、シェルを終了してもプロセスが実行されたままになるように、バックグラウンドとプロセスの放棄の両方への zsh 固有のショートカットを使用します。

于 2021-10-25T13:15:14.203 に答える
-3

まず、次の手順に従います。

ユーザー a として A にログインし、認証キーのペアを生成します。パスフレーズを入力しないでください:

a@A:~> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/a/.ssh/id_rsa): 
Created directory '/home/a/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/a/.ssh/id_rsa.
Your public key has been saved in /home/a/.ssh/id_rsa.pub.
The key fingerprint is:
3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 a@A

ここで、ssh を使用してディレクトリ ~/.ssh をユーザー b として B に作成します (ディレクトリは既に存在している可能性がありますが、問題ありません)。

a@A:~> ssh b@B mkdir -p .ssh
b@B's password: 

最後に、a の新しい公開鍵を b@B:.ssh/authorized_keys に追加し、b のパスワードを最後にもう一度入力します。

a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
b@B's password: 

これからは、パスワードなしで A として a から B として b にログインできます。

a@A:~> ssh b@B

これはパスワードを入力せずに機能します

ssh b@B "cd /some/directory; 実行するプログラム &"

于 2011-06-24T07:07:10.120 に答える