cat命令的语法和用法正确吗? [英] Correct syntax and usage of `cat` command?

查看:208
本文介绍了cat命令的语法和用法正确吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(此问题是对评论,在有关git hooks的答案中)

(This question is a follow-up on this comment, in an answer about git hooks)

我对bash的熟练程度远远不够(到目前为止),无法完全理解备注以及如何采取相应措施。更具体地说,建议我避免以这种方式使用bash命令 cat

I'm far too unskilled in bash (so far) to understand fully the remark and how to act accordingly. More specifically, I've been advised to avoid using bash command cat this way :

echo "$current_branch" $(cat "$1") > "$1"

因为操作顺序取决于特定的外壳,最终可能破坏内容

because the order of operations depends on the specific shell and it could end up destroying the contents of the passed argument, so the commit message itself if I got it right?

此外,如何在单独的步骤中保存内容?

Also, how to "save the contents in a separate step"?

以下内容有意义吗?

tmp = "$1"
echo "$current_branch" $(cat $tmp) > "$1"


推荐答案

建议的问题与覆盖变量无关或参数,但是关于同时读取和写入文件通常是个坏主意。

The proposed issue is not about overwriting variables or arguments, but about the fact that both reading from and writing to a file at the same time is generally a bad idea.

例如,此命令可能看起来像只是写了一个文件本身,而是将其截断:

For example, this command may look like it will just write a file to itself, but instead it truncates it:

cat myfile > myfile   # Truncates the file to size 0

但是,这在您的特定命令中不是问题。由于指定的操作顺序,因此可以保证它可以在POSIX兼容外壳中使用。 表示将在扩展后 进行重定向:

However, this is not a problem in your specific command. It is guaranteed to work in a POSIX compliant shell because the order of operations specify that redirections will happen after expansions:



  1. 应扩展不是变量分配或重定向的单词。如果在扩展后还剩下任何字段,则应将第一个字段视为命令名称,其余字段将作为命令的参数。

  1. The words that are not variable assignments or redirections shall be expanded. If any fields remain following their expansion, the first field shall be considered the command name and remaining fields are the arguments for the command.

重定向


Double-however ,在某种程度上看似无害的修改可能会触发问题,例如在您要对结果运行 sed 的情况下,它仍然有点脆弱。由于重定向(> $ 1 )和命令替换 $(cat $ 1)现在位于单独的命令中,POSIX定义不再为您节省:

Double-however, it's still a bit fragile in the sense that seemingly harmless modifications may trigger the problem, such as if you wanted to run sed on the result. Since the redirection (> "$1") and command substitution $(cat "$1") are now in separate commands, the POSIX definition no longer saves you:

# Command may now randomly result in the original message being deleted
echo "$current_branch $(cat "$1")" | sed -e 's/(c)/©/g' > "$1"

类似地,如果将其重构为函数,它也会突然停止工作:

Similarly, if you refactor it into a function, it will also suddenly stop working:

# Command will now always delete the original message
modify_message() {
  echo "$current_branch $(cat "$1")"
}
modify_message "$1" > "$1"

您可以通过写入临时文件,然后替换原始文件来避免这种情况。

You can avoid this by writing to a temporary file, and then replace your original.

tmp=$(mktemp) || exit
echo "$current_branch $(cat "$1")" > "$tmp"
mv "$tmp" "$1"

这篇关于cat命令的语法和用法正确吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆