如何在不在bash脚本中创建竞争条件的情况下检查文件是否存在?

如果我错了,请纠正我,但根据我所知道的以及我对竞争条件和 TOCTOU(检查时间和使用时间)错误的理解,以这种方式检查文件是否存在:

if [ -f /path/to/file ]; then 
    #File exists do some operations on it
fi

创建竞争条件和 TOCTOU 错误。那么有没有其他方法可以在不创建竞争条件的情况下检查文件或目录是否存在,或者如果它不存在,则可能尝试打开文件并处理错误。

我知道在大多数脚本中使用以前的方法可能不是那么重要,但对我来说最好练习避免这种情况。
谢谢你的帮助。

回答

为避免竞争条件,您可以将文件重命名为第一步锁定条件。在许多文件系统上,这是一个不能同时完成的“原子”操作(一个 inode 写入)。

这样,如果重命名成功,您就可以确定该文件存在并且您的其他进程都没有使用它的原始名称。

例如,使用当前进程 PID 重命名文件:

mv /path/to/file path/to/file.$$
if [ $? = 0 ] ; then
  # Success, we can work on path/to/file.$$, and we're then the only one to do so from 
  # our processes point of view.
  cat path/to/file.$$ # doing something with the file
  # At the end, we can rename/move the file as 'processed'
  mv path/to/file.$$ processed_path/to/file
fi

这样,您还可以对带有 PID 号作为扩展名的文件进行恢复过程。

编辑:正如@Thomas 所主张的,这里是这个解决方案的基本实现,作为 bash 脚本,process. 除非在目录树中,例如:

[`process` 当前目录]
|-->[input] 输入目录,脚本在其中查找要处理的 '*.txt' 文件
|-->[input_path_etl] 输入目录,脚本将在其中放置 ETL 处理过的文件

该脚本要求/proc文件系统进行简单的进程检查。对于垂直可读性,尚未应用SC2181。

该脚本使用 处理文件,./process并且可以./process -r 从其当前路径在崩溃时进行恢复。只是举例说明如何使用mv lock。此处处理 .txt 文件是将文件中的数据虚构加载到数据库中的第一步,第二步是为 ETL 处理器生成虚构文件。

[ `process` current directory ]
|-->[input] input directory where the script look for '*.txt' files to process
|-->[input_path_etl] input directory where the script will place processed file for ETL


以上是如何在不在bash脚本中创建竞争条件的情况下检查文件是否存在?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>