[英]How to get new files coming into a folder while processing files for the same folder in shell script
在我的shell腳本開始時,我有一個FOR循環來掃描一個文件夾,以查看其中是否有文件,如果是,我需要處理每個文件。 每個文件的處理過程將花費一些時間(例如幾分鍾),具體取決於文件夾中有多少個文件。
問題在於:在處理每個文件的過程中,可能會有新文件進入該文件夾,但是我的測試表明,新文件沒有被拾取和處理。 因此,有沒有一種方法可以檢測到FOR循環過程中出現的新文件?
我考慮過定期檢查文件夾中是否有新文件,但我不想再次重新處理現有文件,更重要的是,因為這只是在腳本的開頭,所以我不想FOR循環重復太多次。 謝謝。****
for aFile in "$mydir"/*
do
// some tasks that may take 30 secs or so to finish for each file
done
像這樣的事情呢:
#!/bin/sh -xe
# create some dummy files to start with
touch filea
touch fileb
function analyzeFile() {
echo "analyzing $1"
sleep 10 # dummy for the real stuff you need to do
}
declare stillGettingSomething
declare -A alreadyAnalyzed
stillGettingSomething=true
while [ $stillGettingSomething ]; do
stillGettingSomething=false # prevent endless looping
for i in ./file*; do
# idea: see also http://superuser.com/questions/195598/test-if-element-is-in-array-in-bash
if [[ ${alreadyAnalyzed[$i]} ]]; then
echo "$i was already analyzed before; skipping it immediately"
continue
fi
alreadyAnalyzed[$i]=true # Memorize the file which we visited
stillGettingSomething=true # We found some new file; we have to run another scan iteration later on
analyzeFile $i
# create some new files for the purpose of demonstration
echo "creating file $i-latecreate"
touch $i-latecreate
done
done
該腳本的結果是
+ declare stillGettingSomething
+ declare -A alreadyAnalyzed
+ stillGettingSomething=true
+ '[' true ']'
+ stillGettingSomething=false
+ for i in './file*'
+ [[ -n '' ]]
+ alreadyAnalyzed[$i]=true
+ stillGettingSomething=true
+ analyzeFile ./filea
+ echo 'analyzing ./filea'
analyzing ./filea
+ sleep 10
+ echo 'creating file ./filea-latecreate'
creating file ./filea-latecreate
+ touch ./filea-latecreate
+ for i in './file*'
+ [[ -n '' ]]
+ alreadyAnalyzed[$i]=true
+ stillGettingSomething=true
+ analyzeFile ./fileb
+ echo 'analyzing ./fileb'
analyzing ./fileb
+ sleep 10
+ echo 'creating file ./fileb-latecreate'
creating file ./fileb-latecreate
+ touch ./fileb-latecreate
+ '[' true ']'
+ stillGettingSomething=false
+ for i in './file*'
+ [[ -n true ]]
+ echo './filea was already analyzed before; skipping it immediately'
./filea was already analyzed before; skipping it immediately
+ continue
+ for i in './file*'
+ [[ -n '' ]]
+ alreadyAnalyzed[$i]=true
+ stillGettingSomething=true
+ analyzeFile ./filea-latecreate
+ echo 'analyzing ./filea-latecreate'
analyzing ./filea-latecreate
+ sleep 10
其背后的想法是使用關聯數組,該數組可存儲已處理的文件。 如果文件已被處理,則下一次我們跳過該文件時將跳過該文件。 只要執行一次掃描迭代中至少要獲取一個新文件,我們便會執行此操作。
這是上面編碼的一個清理后的變體,修剪了演示用途的編碼,試圖盡可能地接近原始要求。
#!/bin/sh
function analyzeFile() {
echo "analyzing $1"
sleep 10 # dummy for the real stuff you need to do
}
declare stillGettingSomething
declare -A alreadyAnalyzed
stillGettingSomething=true
while [ $stillGettingSomething ]; do
stillGettingSomething=false # prevent endless looping
for i in "$mydir"/*; do
if [[ ${alreadyAnalyzed[$i]} ]]; then
echo "$i was already analyzed before; skipping it immediately"
continue
fi
alreadyAnalyzed[$i]=true # Memorize the file which we visited
stillGettingSomething=true # We found some new file; we have to run another scan iteration later on
analyzeFile $i
done
done
這是一個有趣的問題,有很多解決方法。 一種方法是跟蹤完成哪些文件,然后在每次循環迭代中處理第一個撤消的文件,例如,
cd "$mydir"
# make a donedir to put placeholder dummy files
mkdir donedir
while true; do
# find first file with no corresponding dummy file in donedir
newfile=`find * -maxdepth 0 -type f |
sed 's/.*/[ ! -f "../donedir/&" ] \&\& echo "&"/' |
sh | head -n1`
# break out of the loop if there aren't any
[ "$newfile" = "" ] && break
# do your thing with $newfile...
# record that you're done with $newfile
touch "donedir/$newfile"
done
一種更有效的策略是在完成處理后將每個文件簡單地移至donedir:
cd "$mydir"
mkdir donedir
while true; do
# find first file
newfile=`find * -maxdepth 0 -type f | head -n1`
# break out of the loop if there aren't any
[ "$newfile" = "" ] && break
# do your thing with $newfile...
# done with $newfile...
mv "$newfile" donedir
done
人們還可以跟蹤例如用EagleRainbow建議的關聯數組來完成哪些文件,但是這種方法的缺點是1.不必要的復雜性,以及2.跨應用程序的不同運行不會自動保留完成的文件腳本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.