Linux 当两个文件都由随机特殊变量命名时,如何不覆盖现有文件

Linux 当两个文件都由随机特殊变量命名时,如何不覆盖现有文件,linux,shell,Linux,Shell,我已经编写了一个基本脚本,用于保存来自大程序不同部分的非空错误文件,因为它们会在一段时间后被删除 我想通过使用bash特殊变量$RANDOM将它们保存在不同的名称下解决了这个问题。它工作得很好,但现在我才意识到我丢失了一些错误文件,可能是因为它被随机命名过程覆盖了。如何在不覆盖旧错误文件的情况下保存新错误文件(不是空的) 我的剧本是: while [ ! -e ${myfile} ]; do for FILE in $( find dirnames -name job.err ) do

我已经编写了一个基本脚本,用于保存来自大程序不同部分的非空错误文件,因为它们会在一段时间后被删除

我想通过使用bash特殊变量
$RANDOM
将它们保存在不同的名称下解决了这个问题。它工作得很好,但现在我才意识到我丢失了一些错误文件,可能是因为它被随机命名过程覆盖了。如何在不覆盖旧错误文件的情况下保存新错误文件(不是空的)

我的剧本是:

while [ ! -e ${myfile} ]; do
 for FILE in $( find dirnames -name job.err )
 do
    if [[ -s ${FILE} ]] ; then
      echo ${FILE} >> LIST
      cp ${FILE} COLLECT/job_${RANDOM}.err
    fi
 done
 sleep 3600
done

好的,对于一个简单的解决方案,只需将从纪元开始的时间(以纳秒为单位)添加到文件名中。虽然它不能保证没有碰撞,但它至少会使碰撞变得非常不可能,特别是当与随机值结合时。例如

cp ${FILE} COLLECT/job_${RANDOM}-$(date +%s.%N).err

使用
$RANDOM
时,发生名称冲突的几率为32767分之一。很有可能

您已经知道如何检查文件是否存在,请使用相同的方法处理文件副本:

copy="COLLECT/job_${RANDOM}.err"
while [[ -e "$copy" ]] ; do
    copy="COLLECT/job_${RANDOM}.err"
done
cp "${FILE}" "$copy"

当然,离32767文件越近,它就越难找到一个免费的目的地。最好使用不依赖随机性的方案。

您可以使用
mktemp
创建一个保证唯一的文件名。例如:

cp "${FILE}" "COLLECT/$(mktemp job_XXXXXXXXX)"

在上述情况下,您将丢失“.err”后缀,但如果您确实需要,可以使用一些额外的代码来解决此问题。

如果脚本并行运行多次(例如,如果脚本经常从cron运行,并且需要一段时间才能完成),这仍然可能覆盖现有文件。在检查文件存在与创建文件之间有一个短暂的时间窗口。如果两个进程同时检查某个特定名称,它们都会看到该名称不存在,然后都尝试创建它。这可以通过只允许一个脚本实例同时运行来解决,例如使用
shlock
。非常感谢。虽然,我没有使用你的想法,但我可以在其他情况下使用它。非常感谢!最后,我使用了使用时间的那个,但我也记住了mktemp。