ssh targetHost &; fg - 動作しませんが、なぜでしょうか?

ssh targetHost &; fg - 動作しませんが、なぜでしょうか?

私は、ssh セッションの pid を取得し (バックグラウンドで実行すると pid が表示されます)、次に fg で ssh セッションに戻ってパスワードを入力するために、次の組み合わせを試していました。

ssh targetHost &; fg

次のエラーが発生します:

-bash: syntax error near unexpected token `;'

この場合、「;」が期待どおりに機能しないのはなぜですか?

私の目的は、ssh セッションを開始してその pid を知ることですが、これをできるだけ少ない行数で行う必要があります。複数の ssh セッションを開始し、それらをバックグラウンドに置き、最後に終了する必要があります。そのために pid が必要なのです。

答え1

2 つの異なるケースを混同しています:

  • foo ; barfooを実行し、終了するまで待ってからbarを実行します
  • foo & barfoo を起動し、それをバックグラウンドに配置し、その後すぐに bar を起動します。

どちらか一方を使用するか決める必要があります。両方を使用することはできません。;)

この問題を解決するには、すべてのジョブをバックグラウンドで実行し、次のようにしてjobpid を一覧表示します。

michas@lenny:~$ sleep 10 &
[1] 18007
michas@lenny:~$ sleep 10 &
[2] 18011
michas@lenny:~$ sleep 10 &
[3] 18015
michas@lenny:~$ sleep 10 &
[4] 18019
michas@lenny:~$ sleep 10 &
[5] 18026
michas@lenny:~$ jobs -p
18007
18011
18015
18019
18026
michas@lenny:~$ 

また、kill シグナルを送信するために必ずしも pid は必要ありません。たとえば、kill %1最初のバックグラウンド プロセスを強制終了します。

答え2

&;は常に間違っています。コンパクトなワンライナーでバックグラウンドで何かを実行したい場合は、 ';' を完全に省略し、&コマンド間で を使用します。

for i in ./*; do my_command "$i" & done

# 見るhttp://mywiki.wooledge.org/BashPitfalls

答え3

が失敗する理由については、すでに他の人が説明しています&;。最後にバックグラウンド プロセスの PID は として保存されることを指摘したいと思います$!。したがって、最後のコマンドの PID には常にアクセスできます。

ssh targetHost & echo $!; fg

これらを終了するには、ssh次のコマンドですべてのセッションを終了できます。

pkill -x ssh

原因xとを完全なコマンド名と一致させることpkillで、またはpgrepが強制終了されないことが保証されます。特定のマシンへの接続のみを強制終了する場合は、次のようにすることもできます。sshdssh-agent

pkill $(pgrep -alx ssh | grep TARGET_IP | cut -d ' ' -f 1)

関連情報