【问题标题】:Bash script that creates a file and then copies it - the copy is sometimes empty创建文件然后复制它的 Bash 脚本 - 副本有时为空
【发布时间】:2014-02-23 15:09:56
【问题描述】:

我在创建 bash 脚本方面相对缺乏经验。我有一个具有以下形式的脚本:

echo "something" >> somefile
echo "somethingelse" >> somefile
rm -f /somepath/somefile
cp somefile /somepath/somefile

这样做是创建一个文件(在实际应用程序中填充了从 Web 表单提交的数据),然后将该文件复制到 /somepath/

有时,新文件的副本是空的,但原始副本包含所有echoed 数据。

这是否可能与竞争条件有关,因为在复制操作之前数据可能尚未刷新到文件中?

【问题讨论】:

    标签: linux bash flush


    【解决方案1】:

    如果这是通过网络表单提交的,我猜您可以在任何给定时间让多个线程访问您的临时文件。

    您要回显到的文件的真实名称是什么,它是唯一的吗?

    尝试为该文件名附加一些独特的内容,例如进程 ID。

    您可以使用以下方式获取进程 ID:$$

    echo "text" >> "tempfile_$$"
    

    这会给你这样的东西:tempfile_1234

    或者更好的是你可以使用一个变量:

    TEMP_FILE="tempfile_$$"
    echo "text" >> $TEMP_FILE
    # Do other stuff, copying, etc.
    rm $TEMP_FILE
    

    【讨论】:

    • 它是在提交 Web 表单时运行还是什么?这可能是一个竞争条件,例如同一脚本的多个实例?
    • 谢谢。真名总是一样的;它从来都不是独一无二的。听起来很糟糕,这实际上只是一个简单的嵌入式 Web 服务器,它的表单不太可能同时被不同的用户访问。我会试试你的建议 - 非常感谢!
    • 没有其他方法可以让您的脚本如您所描述的那样失败 - 一定是某些东西覆盖了文件。
    • 添加更多信息,它正在为嵌入式系统(基于 Arch Linux ARM 的 SBC)的用户提供一种更改其 IP 地址的方法。提交 web 表单时,会调用脚本生成新的 netctl 配置文件,然后将其移动到 /etc/netctl/ 并启用。 (如果有更好的方法可以完全实现这一点,那么我愿意接受建议——也许在一个单独的问题中。)我想知道 netctl 系统是否可以在那时尝试访问该文件。顺便说一句,将rm 更改为mv 以移动而不是复制似乎已经解决了这个问题。
    • @Jay 道歉 - 我应该早点回到这个问题上,但这是一个忙碌的周末。我真的很感谢你的回答。奇怪的是,修复似乎只是简单地mv 文件而不是执行mv。在测试期间,我从未同时访问过 Web 表单。我想我会做的是进一步实验,看看我是否能找到原因的根源,如果我能确定一个,我最终会发布一个答案。我想说你应该把这个答案留在这里,因为它肯定是给定问题的一个可能原因,而且它很有用;我相应地投了赞成票。
    猜你喜欢
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多