簡體   English   中英

在少數服務器上遠程執行命令並在運行時運行經過的計時器

[英]Executing commands remotely on few servers and running elapsed timer while running

我正在嘗試編寫一個腳本,該腳本將在幾個服務器上執行命令並在它們運行時顯示經過的時間。

這是我的代碼,實際上是行不通的...

echo "Starting..."  
server_num=4
cnt=1
SECONDS=0
for ((i=1; i<=$server_num; i++)) ;do
    read -r pid[$i] < <(
        ssh server$i 'nohup "yes | yes | command" > logfile & echo $!'
        )
    echo
    while kill -0 ${pid[@]} 2> /dev/null; do
        sleep 1
        duration=$SECONDS
        echo -n "Please wait... $(($duration / 60)) minutes and $(($duration % 60)) seconds elapsed." $'\r'
        let cnt=cnt+1
        done
    done
wait
sleep 5
echo "completed..."

我究竟做錯了什么 ? 我正在獲取命令的pid,但似乎它們並未在主機上執行。

該腳本的主要問題是后台作業是在遠程系統上啟動的,但是檢查進度是在本地完成的。 編寫這樣的腳本並不容易,因為要考慮很多問題(例如,本地命令,遠程命令持續時間,網絡延遲,連接問題,命令輸出,可重復使用的pid等),每個人都在職業生涯的某一時刻編寫此類腳本,並且每個人都可以從中學到東西,所以我嘗試通過兩種方式來糾正您的腳本,保持您的想法並刪除一些不必要的內容,以便您也可以提高自己的知識水平。

版本1:在遠程服務器上執行命令,並在后台作業中保持連接打開。 一旦在所有主機上啟動該命令,然后在作業數大於0時循環,顯示消息每秒重復一次。 優點:較短的代碼,易於檢查缺點:如果在執行過程中網絡中斷,作業將被中斷。

server_num=4
SECONDS=0
echo "Starting..."
# Start jobs in background wich will execute remote commands that take long
for ((i=1; i<=$server_num; i++)); do
    ssh server$i "sleep 5" &
done
# Now check the progress until all finish
while [[ $(jobs | wc -l) -gt 0 ]]; do
    echo "Please wait... $(jobs | wc -l) jobs still running... $((SECONDS/60)) minutes and $((SECONDS%60)) seconds elapsed."
    sleep 1
    jobs >/dev/null 2>&1
done
echo "completed..."

版本2:在后台啟動后立即在遠程服務器上啟動作業,但在啟動后立即關閉連接,但保留每個主機的作業PID。 然后在正在運行的作業的計數器大於0時循環,每次連接到每個主機並檢查具有保存的PID的進程是否仍然存在,如果是,則遞增計數器並最終顯示一條消息。 優點:不需要保持持久連接打開(以防網絡中斷作業是安全的。)缺點:如果在主機上作業將完成,則檢查仍在該主機上執行(如果在此期間重復使用PID,腳本可能需要更長的時間檢查錯誤的內容)。

server_num=4
SECONDS=0
echo "Starting..."
# Start jobs on remote hosts in background wich will take long
for ((i=1; i<=$server_num; i++)); do
    # save the process ID for each case
    pid[$i]=$(ssh server$i 'nohup bash -c "sleep 12" >logfile 2>&1 & echo $!')
done
# Now check the progress on each host untill all jobs finish
count=${#pid[@]}
while [[ $count -gt 0 ]]; do
    count=0
    for ((i=1; i<=$server_num; i++)); do
        # remotely check if the process id is still in use
        ssh server$i ps -p ${pid[$i]} >/dev/null 2>&1
        if [[ $? -eq 0 ]]; then
            ((count=count+1))
        fi
    done
    echo "Please wait... $count jobs still running... $((SECONDS/60)) minutes and $((SECONDS%60)) seconds elapsed."
    sleep 1
done
echo "completed..."

如果您將此類腳本用於實際工作,那么您將發現其他可以糾正的問題。 最終,建議使用其他專門構建的工具來處理此類任務(並行,dsh等)。祝您好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM