這樣的情況下假設通過ssh運行腳本,而腳本運行時間又比較長的話。會導致sshclient和server長時間無交互而超時,命令運行失敗。
使用bash子進程能夠解決這樣的問題,思路是由子進程運行詳細的邏輯代碼,而由主進程來監控子進程的運行狀態,同一時候向控制台輸出字符來keep alive。
bash創建子進程有多重方式。這里使用“()”,然后用“&”將其放在后台運行。盡管通過“job -p”可以獲取到后台進程的進程ID並使用“wait $PID”的方式可以監控到子進程的返回狀態,如以下的代碼。但這樣的方式相當於堵塞了主進程,無法運行其它動作。
for pid in $(jobs -p); do wait $pid done解決的方法是新建一個標志文件,並將子進程返回值保存在另外一個暫時文件里,主進程通過標志文件和返回值來獲取相關信息。運行其余邏輯。
簡化代碼例如以下,主進程在等待時會一直打印一個旋轉的進度標志。
function doSomething() { local retTmp=$(mktemp) local lock="/tmp/do.lock" touch $lock ( real script to do something echo $?> $retTmp rm -f $lock; )& while [ -f $lock ]; do sleep 0.1 printf "Please wait... %s \r" $f let "t=10#$(date +%N) / 100000000 % 4" case $t in 0) f="/";; 1) f="-";; 2) f="\\";; 3) f="|";; esac done echo local retcode=$(cat $retTmp) rm -f $retTmp return $retcode }
這樣的方式類似於通過fork函數實現相關邏輯,感覺上略微有點笨重,不清楚bash是否有更簡便的方式來實現主子進程的信息同步