我有一个shell脚本,它列出文件夹的文件,然后对它们执行操作(打印成PDF),但我经常得到一个空白的PDF。如果我删除生成的PDF,则始终正确生成新PDF。
我的印象是因为我的脚本在文件完全复制之前就开始打印了(复制是通过OS资源管理器进行的,只有一个另存为,或者只是复制粘贴)。
当有人添加新文件时,绝对不是我管理的,副本来自使用网络共享的用户。
有没有办法有这样的东西?
for inputFile in `ls -l $SearchPattern | grep ^- | awk '{print $9}'`
do
//CHECK_THAT_THE_FILE_HAS_ALREADY_BEEN_FULLY_SAVED_ONCE
//DO_MY_PRINT_HERE
done
答案 0 :(得分:2)
如果您在Linux下运行并且文件系统 local 到您的服务器,那么您可以使用inotify子系统等待文件关闭然后触发操作。 inotify-tools包中包含inotifywait程序,该程序将inotify功能公开给shell脚本。
例如,您可以在以下目录中查看close_write
事件:
inotifywait -e close_write -m /path/to/directory
运行此命令,执行以下操作:
echo hello > /path/to/directory/file
将生成如下输出:
/path/to/directory/ CLOSE_WRITE,CLOSE hello
所以你有生成事件的目录和文件名。在shell脚本中,您可以将其传递到循环中:
inotifywait -e close_write -m /path/to/directory | while read dir flags file; do
...do something with the file...
done
答案 1 :(得分:1)
有人指出,使用文件修改时间可能很有用。我很快就完成了这个可能有用的脚本。它将等待自给定文件的最后修改时间起经过5秒:
#!/bin/bash
function getTimeFromLastChange() {
file=${1}
let lastAccess=$(stat --format=%Y ${file})
let now=$(date +%s)
let timePassed=$((now - lastAccess))
echo ${timePassed}
}
file=./test
while [ true ]; do
let lastChange=$(getTimeFromLastChange ${file})
if [ "${lastChange}" -lt 5 ]; then
echo "waiting"
sleep 1
else
echo "done"
exit
fi
done
echo ${timePassed}
这里的关键是“getTimeFromLastChange”函数,它使用stat(http://linux.die.net/man/1/stat)来获取自unix纪元时间以来秒内给定文件的最后修改时间。然后,它将使用日期(http://linux.die.net/man/1/date)获取当前时间(再次,自unix纪元时间以来的秒数),减去它们,并计算自从以来的总秒数最后修改时间。
主循环将等到一些“安全”秒数过去。因此,您可以尝试调整此参数并打印几秒钟前写入/修改过的文件。
示例运行:
marcelog@host ~ $ touch ./test
marcelog@host ~ $ ./try.sh
waiting
waiting
waiting
done
这不是100%安全。但我认为值得一试。
希望它有所帮助!
答案 2 :(得分:0)
您应该检查数据的修改时间并确定一个阈值。 没有其他(简单)方法可以查看文件上是否还有待处理的操作。
所以你应该使用
ls -l -t
在你找到上面的陈述并通过“排序”来管道你的时间阈值。
问候
答案 3 :(得分:0)
我最后使用
for inputFile in `find $SearchPattern2 -maxdepth 1 -type f -cmin +1 -iname "*.pdf"`
-cmin +1表示要查找,只需要列出修改时间> 1分钟前的文件。
这不是100%安全,但它会以很大的余量处理我的所有情况。
我在几秒钟内没有找到如何做到这一点