bash - `cat` 命令的正确语法和用法?
问题描述
(这个问题是这个评论的后续,在关于 git hooks 的回答中)
我在 bash 方面(到目前为止)太不熟练了,无法完全理解这句话以及如何采取相应的行动。更具体地说,有人建议我避免以cat
这种方式使用 bash 命令:
echo "$current_branch" $(cat "$1") > "$1"
因为操作的顺序取决于特定的shell,它最终可能会破坏传递参数的内容,所以如果我做对了,提交消息本身?
另外,如何“将内容保存在单独的步骤中”?
以下有什么意义吗?
tmp = "$1"
echo "$current_branch" $(cat $tmp) > "$1"
解决方案
提议的问题不是关于覆盖变量或参数,而是关于同时读取和写入文件通常是一个坏主意的事实。
例如,此命令可能看起来只是将文件写入自身,但实际上会截断它:
cat myfile > myfile # Truncates the file to size 0
但是,这在您的特定命令中不是问题。它保证可以在符合 POSIX 的 shell 中工作,因为操作顺序指定重定向将在扩展之后发生:
不是变量赋值或重定向的词应被扩展。如果扩展后仍有任何字段,则第一个字段应视为命令名称,其余字段是命令的参数。
重定向应按照重定向中的描述执行。
但是,从看似无害的修改可能引发问题的意义上说,它仍然有点脆弱,例如如果您想sed
在结果上运行。由于重定向 ( > "$1"
) 和命令替换$(cat "$1")
现在在单独的命令中,POSIX 定义不再为您节省:
# Command may now randomly result in the original message being deleted
echo "$current_branch $(cat "$1")" | sed -e 's/(c)/©/g' > "$1"
同样,如果你将它重构为一个函数,它也会突然停止工作:
# Command will now always delete the original message
modify_message() {
echo "$current_branch $(cat "$1")"
}
modify_message "$1" > "$1"
您可以通过写入临时文件来避免这种情况,然后替换您的原始文件。
tmp=$(mktemp) || exit
echo "$current_branch $(cat "$1")" > "$tmp"
mv "$tmp" "$1"
推荐阅读
- c# - 如何在查询中将数据插入没有 ID 的表中?
- python - 正确使用 UserList 和对象
- python - 记忆游戏,检测两个图像相同的问题
- javascript - 用于将 html5 视频跳到最后的按钮
- php - 检查类别是否存在于具有 csv 值格式的 MYSQLI 表列中
- php - 计算命名/创建列的与计数/SQL 查询相乘
- java - 如何以 opencv 作为依赖项正确构建我的 javaFX 应用程序?
- ruby-on-rails - React 客户端无法正确分发接收到的 ActionCable 广播
- php - PHP从基本授权获取用户名
- javascript - UniSharp laravel-filemanager 与 TinyMCE 5 的集成