Shell-Script

通過 ssh 發送命令而不是等到離開終端的腳本

  • May 8, 2019

我有幾台電腦,通過乙太網交換機組合成網路。所有人都在執行 Fedora 伺服器並連接到 Internet。

我需要的是一個腳本,它:

  • 連接到列表中的所有節點
  • 發送命令或命令包(如更新全部或安裝一些包)
  • 關閉連接,但保持命令在目標機器上執行

目前,腳本是:

#!/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它被轉發到該腳本開始的主電腦。

如何解決?

我在這裡這里這裡找到了關於可能解決方案的文章,但它們沒有用。

這些類型的呼叫總是很棘手,因為您必須確保在正確的位置對事物進行評估。IE。添加正確數量的反斜杠。

如果你這樣做

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

它應該做你想做的(注意-n保持標準輸入關閉)。time您可以通過在 sshpass 命令之前添加或通過執行netstat$SCRIPT1檢查打開的連接來驗證 ssh 連接是否確實關閉。

您需要確保 stdin、stdout 和 stderr 都已關閉,否則ssh將等到它們關閉,即使程序已被後台處理。

如果上述方法不起作用,則可能需要對命令行參數進行額外評估sshpass。此外,使用單引號$SCRIPT1將內部例如 shell 變數的擴展延遲$SCRIPT1到遠端端。

現在,即使您可以使用這種方法完成任務,我還是建議您使用專門用於這種自動化的工具,例如 Ansible ( https://docs.ansible.com/ansible/latest/index.html )。使用後台方法,您必須手動(或使用其他開發的工具)檢查命令是否成功,或者是否已完成執行。

引用自:https://unix.stackexchange.com/questions/517308