DIRECTORIES=( group1 group2 group3 group4 group5 )
PIDS=()
function GetFileSpace() {
shopt -s nullglob
TARGETS=(/home/${1}/data/*)
for ITEM in "${TARGETS[@]}"
do
# Here we launch du on a user in the background
# And then add their process id to PIDS
du -hs $ITEM >> ./${1}_filespace.txt &
PIDS =($!)
done
}
# Here I launch function GetFileSpace for each group.
for GROUP in "${DIRECTORIES[@]}"
do
echo $GROUP
# Store standard error to collect files with bad permissions
GetFileSpace $GROUP 2>> ./${GROUP}_permission_denied.txt &
done
for PID in "${PIDS[@]}"
do
wait $PID
done
echo "Formatting Results..."
# The script will after this, but it isn't relevant.
我正在嘗試撰寫一個腳本來監視 5 個組中單個用戶的存盤量和檔案權限。
|_home # For additional reference to understand my code,
|_group1 # directories are laid out like this
| |_data
| |_user1
| |_user2
| |_user3
|
|_group2
|_data
|_user4
|_user5
首先,我使用回圈GetFileSpace為DIRECTORIES. 然后,此函式會du -sh針對在組中找到的每個用戶運行。
為了加快整個程序,我在GetFileSpace后臺du -sh使用 &. 這使得一切都可以幾乎同時運行,這需要更少的時間。
我的問題是,在我啟動這些行程后,我希望我的腳本等待每個后臺實體du -sh完成,然后再繼續下一步。
為此,我嘗試在陣列中啟動每個任務后收集行程 ID PIDS。然后我嘗試遍歷陣列并等待每個 PID 直到所有子行程完成。不幸的是,這似乎不起作用。該腳本du -sh為每個用戶正確啟動,但隨后立即嘗試繼續進行下一步,中斷。
那么我的問題是,為什么我的腳本不等待我的后臺任務完成,我該如何實作這種行為?
最后一點,我已經嘗試了其他幾種方法來完成這個 SO post,但也無法讓它們作業。
uj5u.com熱心網友回復:
GetFileSpace ... &
您正在將整個函式作為子行程運行。所以它immediately tries to move on to the next step并PID沒有設定,導致它在子行程中設定。
不要在后臺運行它。
GetFileSpace ... # no & on the end.
注意:考慮使用xargs或 GNU parallel。腳本區域變數首選小寫。參考變數擴展。使用 shellcheck 檢查此類錯誤。
work() {
tmp=$(du -hs "$2")
echo "$tmp" >> "./${1}_filespace.txt"
}
export -f work
for i in "${directories[@]}"; do
printf "$i %s\n" /home/${1}/data/*
done | xargs -n2 -P$(nproc) bash -c 'work "$@"' _
請注意,當作業受 I/O 限制時,如果它在一張磁盤上,則運行多個行程(尤其是沒有上限)并沒有太大幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/491441.html
上一篇:請使用<&解釋這個shell腳本
