Answers:
cat /dev/null > file.txt
猫是无用的。
基本上cat /dev/null
只是导致cat
什么都不输出。是的,它可以工作,但是许多人对此并不满意,因为它会导致调用不必要的外部过程。
这是很常见的事情之一,因为它很常见。
> file.txt
在大多数shell上都可以使用just ,但是它并不是完全可移植的。如果要完全便携,可以使用以下替代方法:
true > file.txt
: > file.txt
两个:
和true
输出没有数据,并且是shell内建(而cat
是外部实用程序),因此它们更轻,更“适当的”。
更新:
正如tylerl在他的评论中提到的那样,还有>| file.txt
语法。
大多数shell都有一个设置,可以防止它们通过截断现有文件>
。您必须>|
改为使用。当您确实要附加时,这是为了防止人为错误>>
。您可以使用打开行为set -C
。
因此,我认为截断文件的最简单,最适当和可移植的方法是:
:>| file.txt
>| file
是一个更明确的截断。
true
不需要内置,传统上不是。:
建在伯恩家族的所有贝壳中。:
是每个POSIX的一个特殊内置函数(: > file
例如,如果file
无法打开以在POSIX Shell中进行写操作,则会退出该Shell ),但true
不是。POSIX甚至提到它:
可能比某些系统更有效true
。
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中不带命令的重定向,假定使用默认命令(cat
否则,仅使用stdin重定向的传呼机),可以使用NULLCMD和READNULLCMD变量进行调整。灵感来自的类似功能(t)csh
:
在UnixV7中不执行重定向,因为:
注释领导者和null命令之间进行了中途解释。后来,它们像所有内建程序一样,如果重定向失败,则退出外壳。:
和 eval
是特殊的内置插件,如果重定向失败,则会退出外壳程序(bash
仅在POSIX模式下会这样做)。(t)csh
,它定义了一个null标签(用于goto
),因此goto ''
将在那里分支。如果重定向失败,则退出外壳。$PATH
(:
一般不; true
,cat
,cp
和printf
通常是(POSIX要求它们))。file
但是,如果是到不存在文件的符号链接,则某些cp
实现(例如GNU的实现)将拒绝创建该文件。(本节是主观的)
> file
。这>
看起来太像一个提示或注释。另外,我在阅读时会问的问题(大多数shell都会抱怨这一点)您要重定向的输出什么?。: > file
。:
被称为no-op命令。因此,立即读取为生成一个空文件。但是,这里再次:
很容易错过和/或将其视为提示。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的外壳中内置。
printf
内置了大多数现代的Bourne式外壳和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 {} +
)。
就个人而言,我使用的: > file
是类似Bourne的贝壳,如今除了使用类似的Bourne以外的贝壳,什么也不要使用。
dd of=file count=0
呢
dd
(至少像Solaris 10一样),将count=0
被忽略。dd if=/dev/null of=file
会更便携。无论如何,那都是独立于shell的。
cp /dev/null file
,对吧?
cp /dev/null file
是一个常见的成语。我仅限于这些,重点不是列出所有可能的方式。
您可能要看一下truncate
,它确实可以做到:截断文件。
例如:
truncate --size 0 file.txt
这可能比使用慢true > file.txt
。
但是,我的主要观点是:truncate
用于截断文件,而使用>则具有截断文件的副作用。
truncate
可用,但是C库>
和unistd
C库都不可用吗?
truncate
是FreeBSD实用程序,相对来说最近(2008年)添加到了GNU coreutils中(尽管--size
GNU长选项样式是GNU特定的),因此它在非GNU或FreeBSD系统中不可用,并且在较旧的GNU系统中不可用,我不会说它是便携式的。cp /dev/null file
无需外壳重定向即可工作,并且更加便携。
答案取决于什么 file.txt
以及如何写入!
我会举一个常见的用例:您的日志文件越来越多, file.txt
,并希望对其进行轮换。
因此,例如,您将复制file.txt
到file.txt.save
,然后截断file.txt
。
在这种情况下,如果文件不是由another_process
(例如:another_process
可能是一个输出到该文件的程序,例如记录某些内容的程序),那么您的两个建议是等效的,并且都可以正常工作(但第二个建议是可取的)第一个“ cat / dev / null> file.txt”是Cat的无用用法,并且还会打开并读取/ dev / null)。
但是真正的麻烦是如果other_process
仍然处于活动状态,并且仍然具有打开file.txt的句柄。
然后,根据other process
文件的打开方式,出现两种主要情况:
如果other_process
以正常方式打开它,则该句柄仍将指向文件中的先前位置,例如,偏移量为1200个字节。因此,下一次写操作将从偏移量1200开始,因此,您将再次拥有1200bytes文件(+所写的other_process),其中包含1200个前导空字符!我想不是你想要的。
如果在“追加模式”下other_process
打开file.txt
,则每次写入时,指针都会主动寻找到文件末尾。因此,当您截断它时,它将“搜索”到字节0,并且不会有不良影响!这就是您想要的(...通常!)
请注意,这意味着在截断文件时,需要确保所有other_process
仍在写入该位置的文件都已在“追加”模式下将其打开。否则,您需要停止这些操作other_process
,然后重新启动它们,以便它们开始指向文件的开头而不是先前的位置。
参考:https : //stackoverflow.com/a/16720582/1841533进行了更简洁的解释,并在/programming//a/984761/1841533上介绍了正常模式和附加模式日志记录之间的区别的简短示例
cat /dev/null > file
和a 之间的区别> file
是a cat /dev/null
,对文件没有影响。
我喜欢并经常使用它,因为它看起来更干净,而不像有人不小心按了回车键:
echo -n "" > file.txt
也应该是内置的吗?
echo
实现不支持-n
(并且将-n<SPC><NL>
在此处输出。printf '' > file.txt
会更加便携(至少在现代/ POSIX系统中))