cat 和 '>' 之间的差异将文件清零

cat 和 '>' 之间的差异将文件清零

这两个命令在将文件清零的方式上有什么不同吗?后者是前者的更短方法吗?幕后发生了什么?

两个都

$ cat /dev/null > file.txt

$ > file.txt 

屈服

-rw-r--r--  1 user  wheel  0 May 18 10:33 file.txt

答案1

cat /dev/null > file.txt是一个对猫的无用利用

基本上cat /dev/null只是导致cat什么也不输出。是的,它确实有效,但许多人不赞成它,因为它会导致调用不必要的外部进程。
这是常见的事情之一,因为它很常见。

使用 just> file.txt可以在大多数 shell 上运行,但它并不完全可移植。如果您想要完全便携,以下是不错的选择:

true > file.txt
: > file.txt

:和都不true输出数据,并且是 shell 内置函数(而cat是外部实用程序),因此它们更轻且更“合适”。

 

更新:

正如 tylerl 在他的评论中提到的,还有语法>| file.txt

大多数 shell 都有一个设置,可以防止它们通过>.您必须使用>|它来代替。这是为了防止当您真正想要附加 时出现人为错误>>。您可以使用 来打开该行为set -C

因此,我认为截断文件的最简单、最合适和可移植的方法是:

:>| file.txt

答案2

在便携性方面:

                      Bourne POSIX  zsh    csh/tcsh  rc/es  fish
> file                Y      Y      N(1)   N(1)      N      N
: > file              N/Y(2) Y(3)   Y      Y(4)      N(5)   N(5)
true > file           Y(5)   Y      Y      Y(5)      Y(5)   Y(5)
cat /dev/null > file  Y(5)   Y      Y(5)   Y(5)      Y(5)   Y(5)
eval > file           Y(3,8) Y(3)   Y      Y(6)      Y      Y
cp /dev/null file (7) Y(5)   Y      Y(5)   Y(5)      Y(5)   Y(5)
printf '' > file      Y(5)   Y      Y      Y(5)      Y(5)   Y

笔记:

  1. 除了在shksh仿真中,对于没有命令的重定向,在 zsh 中,假定使用默认命令(仅用于 stdin 重定向的寻呼机,cat否则),可以使用 NULLCMD 和 READNULLCMD 变量进行调整。这是受到类似功能的启发(t)csh
  2. :UnixV7 中最初不执行重定向,因为:它是在注释引导符和空命令之间进行解释的。后来它们就像所有内置函数一样,如果重定向失败,就会退出 shell。
  3. :作为eval特殊的内置函数,如果重定向失败,则会退出 shell(bash仅在 POSIX 模式下执行)。
  4. 有趣的是,在 中(t)csh,定义了一个空标签(对于goto),因此goto ''那里会有分支。如果重定向失败,则退出 shell。
  5. 除非/如果相应的命令可用$PATH:通常不是;truecatcp并且printf通常是(POSIX 需要它们))。
  6. 如果重定向失败,则退出 shell。
  7. 然而,如果file是指向不存在文件的符号链接,则某些cp实现(例如 GNU 的实现)将拒绝创建它。
  8. Bourne shell 的初始版本但不支持重定向内置函数

在易读性方面:

(这部分是非常主观的)

  • > file。这>看起来太像提示或评论了。另外,在阅读该内容时我会问的问题(大多数 shell 都会抱怨同样的问题)是您到底要重定向什么输出?
  • : > file:称为无操作命令。因此,这会直接读取为生成一个空文件。然而,同样,这:很容易被错过和/或被视为提示。
  • true > file:布尔值与重定向或文件内容有什么关系?这里是什么意思呢?当我读到这句话时,我首先想到的是。
  • cat /dev/null > file连接/dev/nullfile cat通常被视为转储文件内容的命令,这仍然有意义:转储内容空文件到file,虽然说起来有点绕cp /dev/null file,但还是可以理解的。
  • cp /dev/null file。复制内容空文件file。这是有道理的,尽管有人不知道cp默认情况下是如何做的,可能会认为您也在尝试制造file一个null设备。
  • eval > file或者eval '' > file。不运行任何内容并将其输出重定向到file.我感觉合理。奇怪的是,这不是一个常见的习语。
  • printf '' > file: 明确印刷文件中没有任何内容。对我来说最有意义的一个。

在性能方面

区别在于我们是否使用内置的 shell。如果没有,则必须分叉进程,加载并执行命令。

eval保证可以在所有 shell 中构建。:在任何可用的地方都是内置的(Bourne/csh 喜欢)。true仅内置于类似 Bourne 的 shell 中。

printf内置了最现代的类似 Bourne 的 shell 和fish.

cp并且cat一般都不是内置的。

现在cp /dev/null file不调用 shell 重定向,因此:

find . -exec cp /dev/null {} \;

将比以下更有效:

find . -exec sh -c '> "$1"' sh {} \;

(虽然不一定比:

find . -exec sh -c 'for f do : > "$f"; done' sh {} +

)。

亲自

就我个人而言,我在类似 Bourne 的 shell 中使用: > file,并且现在除了类似 Bourne 的 shell 之外不使用任何其他东西。

答案3

您可能想看看truncate,它正是这样做的:截断文件。

例如:

truncate --size 0 file.txt

这可能比使用true > file.txt.

然而,我的主要观点是:truncate用于截断文件,而使用 > 具有截断文件的副作用。

答案4

我喜欢这个并经常使用它,因为它看起来更干净,不像有人意外按下返回键:

echo -n "" > file.txt

也应该是内置的吧?

相关内容