Esto resultó ser causado por una condición de carrera. cpcomprueba si el archivo de destino ya existe y, si no, lo sobrescribe. El problema estaba sucediendo porque este cpcomando se ejecutaba dos veces en paralelo, lo que ocasionaba que el archivo en cuestión apareciera a veces después de verificar si existía, pero antes del intento de crear el archivo. El straceresultado se ve así:
# 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)
Aquí hay un código bash utilizado para atrapar esto:
#!/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
Este mismo error puede ocurrir con mkdir -pcualquier otra acción que intente sobrescribir un archivo. Usar flockpuede ayudar a evitar condiciones de carrera en casos como este.
||operador. Una especie de intento / captura de un pobre. Es decir,cp ... || echo "skip copying due to other thread". O algo similar ...cpcp.