无法创建常规文件“文件名”:文件存在

lut*_*zky 26 cp concurrency

我在我的一个构建脚本中收到了这个奇怪的错误消息 -cp失败,返回错误“文件存在”。我什至尝试使用cp -f,如果文件存在,它应该覆盖文件,但错误仍然出现。cp当我手动执行时,运行以覆盖现有文件效果很好。什么可能导致此错误?

lut*_*zky 27

结果证明这是由竞争条件引起的。cp检查目标文件是否已经存在,如果不存在 - 覆盖它。出现问题是因为此cp命令并行运行两次,导致有时会检查是否存在后但尝试创建文件之前出现有问题的文件。该strace输出如下所示:

# Command was "cp a b"
stat("b", 0x7fff89510620)               = -1 ENOENT (No such file or directory)
stat("a", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("b", 0x7fff895103a0)               = -1 ENOENT (No such file or directory)
# File b will be created at this point in time
open("a", O_RDONLY)                     = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
open("b", O_WRONLY|O_CREAT|O_EXCL, 0644) = -1 EEXIST (File exists)
Run Code Online (Sandbox Code Playgroud)

这是用于捕获此内容的一些 bash 代码:

# Command was "cp a b"
stat("b", 0x7fff89510620)               = -1 ENOENT (No such file or directory)
stat("a", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("b", 0x7fff895103a0)               = -1 ENOENT (No such file or directory)
# File b will be created at this point in time
open("a", O_RDONLY)                     = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
open("b", O_WRONLY|O_CREAT|O_EXCL, 0644) = -1 EEXIST (File exists)
Run Code Online (Sandbox Code Playgroud)

mkdir -p尝试覆盖文件的任何其他操作或任何其他操作都可能发生相同的错误。flock在这种情况下,使用可以帮助避免竞争条件。

  • 我在运行单个“cp”时遇到了这个问题 (6认同)