ターミナルを離れるのを待つのではなく、SSH経由でコマンドを送信するスクリプト

ターミナルを離れるのを待つのではなく、SSH経由でコマンドを送信するスクリプト

イーサネットスイッチを介して複数のコンピュータがネットワークにグループ化されています。これらはすべてFedoraサーバーを実行し、インターネットに接続されています。

私に必要なのは、次のスクリプトです。

  • リスト内のすべてのノードに接続
  • コマンドまたはコマンドパッケージの送信(例:フルアップデートまたは特定のパッケージのインストール)
  • 接続を閉じますが、ターゲットシステムでコマンドの実行を維持します。

現在のスクリプトは次のとおりです。

#!/bin/bash
targets_username='username'
targets_password='password'
targets_IPs=( 192.168.1.100 192.168.1.101 192.168.1.102 )

SCRIPT1='dnf update -y'
SCRIPT2='dnf update -y && poweroff'

for IP in ${targets_IPs[@]}; do
        export SSHPASS=$targets_password
        script="nohup sh -c \"( ( $SCRIPT1 & > /dev/null) &)\""
        echo $IP
        echo $script
        sshpass -e ssh -o StrictHostKeyChecking=no -l $targets_username@$IP $script
done

問題は次のとおりです。

  • 接続が閉じると、コマンドの実行が停止します。
  • たとえば、コマンドに追加のコマンドが含まれている場合、またはホストコンピュータに渡されると、rebootそのpoweroffホストコンピュータでスクリプトが起動されます。

この問題をどのように解決しますか?

投稿を見つけましたここここそしてここ考えられる解決策について説明しましたが、うまくいきません。

答え1

このタイプの通貨は、正しい場所で物事を評価していることを確認する必要があるため、常に面倒です。つまり。正しい数のバックスラッシュを追加してください。

そうすれば

script="sh -c \"nohup sh -c '$SCRIPT1' > /dev/null 2>&1 & \""
sshpass -e ssh -n -o StrictHostKeyChecking=no -l $targets_username $IP "$script"

必要に応じて動作する必要があります(-nstdinを閉じてください)。timeSSH接続の前にsshpassコマンドを追加または実行し、開いている接続を確認して、netstatSSH$SCRIPT1接続が実際に閉じられていることを確認できます。

stdin、stdout、およびstderrがすべて閉じていることを確認する必要があります。それ以外の場合は、sshプロセスがバックグラウンドに切り替えても閉じるまで待つ必要があります。

上記の方法がうまくいかない場合は、コマンドライン引数をさらに評価することができますsshpass。また、一重引用符を使用すると、リモート側までの$SCRIPT1内部変数(シェル変数など)の拡張が遅れます。$SCRIPT1

これでこのアプローチを使用して操作を実行できますが、Ansible(https://docs.ansible.com/ansible/latest/index.html)。バックグラウンドアプローチでは、コマンドが成功したか、実行が完了したかを手動で(または他の開発されたツールを使用して)確認する必要があります。

関連情報