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