не может создать обычный файл 'filename': файл существует

23

Я получаю это странное сообщение об ошибке в одном из моих сценариев сборки - cpне удается, возвращая ошибку «Файл существует». Я даже пытался использовать cp -f, который должен перезаписать файл, если он существует, но ошибка все еще появляется. Запуск cpперезаписать существующие файлы отлично работает, когда я делаю это вручную. Что может вызвать эту ошибку?

Луцкая
источник

Ответы:

25

Это оказалось вызвано состоянием гонки. 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)

Вот некоторый код bash, используемый для этого:

#!/bin/bash

touch a

f() {
  while true; do
    rm -f b
    strace -o /tmp/cp${BASHPID}.trace cp a b || break
  done
}

cleanup() {
  kill -9 %1 %2
}

f &
f &

trap cleanup exit

wait

Та же самая ошибка может произойти с mkdir -pлюбым другим действием, которое пытается перезаписать файл. Использование flockможет помочь избежать условий гонки в таких случаях.

Луцкая
источник
Я столкнулся с точно такой же ситуацией. Я решил справиться с этим через ||оператора. Вроде попробуйте / поймать бедняка. Т.е., cp ... || echo "skip copying due to other thread". Или что-то подобное ...
icfantv
Я столкнулся с этой проблемой во время запуска синглаcp
ZhaoGang
Столкнулся с той же проблемой. Как вы это отладили?
CIsForCookies,
Получил препятствие на провал cp.
Луцкий