这两个命令在将文件清零的方式上有什么不同吗?后者是前者的更短方法吗?幕后发生了什么?
两个都
$ 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
笔记:
- 除了在
sh
或ksh
仿真中,对于没有命令的重定向,在 zsh 中,假定使用默认命令(仅用于 stdin 重定向的寻呼机,cat
否则),可以使用 NULLCMD 和 READNULLCMD 变量进行调整。这是受到类似功能的启发(t)csh
:
UnixV7 中最初不执行重定向,因为:
它是在注释引导符和空命令之间进行解释的。后来它们就像所有内置函数一样,如果重定向失败,就会退出 shell。:
作为eval
特殊的内置函数,如果重定向失败,则会退出 shell(bash
仅在 POSIX 模式下执行)。- 有趣的是,在 中
(t)csh
,定义了一个空标签(对于goto
),因此goto ''
那里会有分支。如果重定向失败,则退出 shell。 - 除非/如果相应的命令可用
$PATH
(:
通常不是;true
,cat
,cp
并且printf
通常是(POSIX 需要它们))。 - 如果重定向失败,则退出 shell。
- 然而,如果
file
是指向不存在文件的符号链接,则某些cp
实现(例如 GNU 的实现)将拒绝创建它。 - Bourne shell 的初始版本但不支持重定向内置函数
在易读性方面:
(这部分是非常主观的)
> file
。这>
看起来太像提示或评论了。另外,在阅读该内容时我会问的问题(大多数 shell 都会抱怨同样的问题)是您到底要重定向什么输出?。: > file
。:
称为无操作命令。因此,这会直接读取为生成一个空文件。然而,同样,这:
很容易被错过和/或被视为提示。true > file
:布尔值与重定向或文件内容有什么关系?这里是什么意思呢?当我读到这句话时,我首先想到的是。cat /dev/null > file
。连接/dev/null
到file
?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
也应该是内置的吧?