這樣的情況下假設通過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是否有更簡便的方式來實現主子進程的信息同步
