我遇到下面代码的问题,它执行数组和if
语句块以检查文件是否处于活动状态。为了进行调试,我使用-x
运行脚本,并且在比较[ … ]
中的两个值时缺少值。我搜索了很多网站以找到答案,但一直没能这样做。如果该文件处于活动状态并且不会被删除,那么该块的问题或解决方法是什么?
#!/bin/bash
#---- parameters check----#
if ( [ "$2" -le "0" ] )
then
echo 'Invalid number of days...'
echo ''
echo 'The number of days must be greater then 0'
exit 1;
fi
#----variables----#
Days="$2"
timestamp=$(date +%Y%m%d_%H%M%S)
FILEFOLDER="$1"
logfile=~/"log_purge_$timestamp.txt"
#----foldercheck----#
if [ -d $FILEFOLDER ]
then
echo "File Folder Directory $FILEFOLDER is set." | tee "$logfile"
else
echo "File Folder Directory $FILEFOLDER does not exist! Process will
Exit."
exit 1;
fi
#----Find if the file is In Use through Array and IF---#
files_check=($(find "$FILEFOLDER" -type f -mtime +"$Days" -print))
for f_c in "${files_check[@]}"
do
if [ "${f_c}" == "$( lsof | grep "$f_c")" ]
then
echo "$f_c is in use rite now,quiting the process"
exit 1
fi
done
echo "No file is in Use right now. Safe to remove"
#---Total Number of Files & Purge ---#
files_num=$(find "$FILEFOLDER" -type f -mtime +"$Days" | wc -l)
echo "Total number of files" $files_num | tee -a "$logfile"
find "$FILEFOLDER" -type f -mtime +"$Days" -print | sed "s|$FILEFOLDER||g" | tee -a $logfile
echo "Purging the files now ....."
find "$FILEFOLDER" -type f -mtime +"$Days" -exec rm {} \;`
答案 0 :(得分:1)
在我的机器上,lsof
会产生类似
LookupVie 75408 jleffler 14r REG 1,4 129990 1353198 /System/Library/CoreServices/SystemAppearance.bundle/Contents/Resources/AccessibilityVibrantLightAppearance.car
这显然与文件名不同,因此平等不会起作用。您可以使用grep -o
(仅输出匹配的文本)。即使这样,如果两个或多个进程打开相同的文件,您将获得多行匹配输出,这样您就不会相等。您真的想检查grep
是否找到文件的状态:
if lsof | grep -q -e "$f_c"
then …
fi
您的遗留问题是您检查的文件名是否包含空格或换行符等,或者您检查的名称是否可以作为其他名称的一部分嵌入。在这种情况下,您需要一个更复杂的正则表达式(可能就像在末尾添加一个美元和前一个空格一样简单):
if lsof | grep -q -e "[[:space:]]$f_c$"
名称中的空格或换行符会影响file_check=($(find …))
的使用。
此外,lsof
相当昂贵。您可以更好地运行一次并捕获结果。您无论如何都面临着TOCTOU(检查时间,使用时间)问题 - 脚本看起来可能没有使用该文件,但现在可能正在使用,反之亦然(文件在检查时正在使用,但是该文件已不再使用。)