为什么将文本处理结果写回输入文件的这两个命令的行为如此不同?

为什么将文本处理结果写回输入文件的这两个命令的行为如此不同?

我有一个文件authorized_keys,想要删除重复的内容,即删除重复的条目。

我找到了两种可能的解决方案来实现这一目标:

  1. 使用catuniq,然后将输出重定向到原始文件:
    cat authorized_keys | uniq > authorized_keys
    
  2. sort与选项一起使用-o
    sort -u ~/.ssh/authorized_keys -o ~/.ssh/authorized_keys
    

但是,只有第二个选项有效。第一种方法将产生一个空文件。

如果我将输出重定向到另一个文件,如

cat authorized_keys | uniq > authorized_keys_2

新文件具有正确的内容,而

cat authorized_keys | uniq > authorized_keys

留给我一个空的authorized_keys

请帮助我理解这两种方法之间的区别。

答案1

您的第一个解决方案将不起作用,因为您正在同时读取和写入文件。这样做会导致一个空文件,因为重定向(即“>”符号)由 shell 处理,并指示 shell 首先打开文件进行写入,从而将其清空。然后你的命令,即

cat authorized_keys | uniq

已执行,但由于文件authorized_keys现在为空,因此会导致空输出。为了避免这样的问题,您可以使用临时文件,就像您用来authorized_keys_2存储输入一样,然后用临时文件覆盖原始文件

答案2

扩展西斯莫尔的回答...

来自bash 手册页

Redirecting Output

Redirection of output causes the file whose name results from the expansion
of word to be opened for writing on file descriptor n, or the standard 
output (file descriptor 1) if n is not specified. If the file does not exist 
it is created; if it does exist it is truncated to zero size. 

您的文件authorized_keys确实存在,因此被截断为零,在执行命令之前

然后 cat零长度文件,因此生成的文件为空。

这个过程的深入解释是这个答案shell 的控制和重定向运算符是什么?

相关内容