Shell-Script
通過 ssh 發送命令而不是等到離開終端的腳本
我有幾台電腦,通過乙太網交換機組合成網路。所有人都在執行 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 )。使用後台方法,您必須手動(或使用其他開發的工具)檢查命令是否成功,或者是否已完成執行。