为什么将sed输出重定向到同一输入文件会使我的机器无响应?


13

我试图sed替换大文件(100 MB)中的某些关键字。我没有意识到-i(inplace)选项,所以我的第一次尝试是这样重定向:

sed 's/original/edited/g' file.log >> file.log

之后发生的事情是我的PC停了下来,几乎没有键盘输入。我尝试使用其他控制台Ctrl+ Alt+,F1但在缓慢输入用户名后,它也停止了运行。没有键盘,我唯一的选择是对机器进行硬件复位。登录后,我看到file.log约为8 GB。

我真的很想了解为什么执行该命令会使系统变得无响应,以及在系统级别是否存在触发警报并杀死令人讨厌的进程的机制?


7
这是单核计算机吗?这本来应该让现代计算机崩溃的,这似乎很奇怪。是的,已填满磁盘。是的,用完了其中一个核心的100%。但是完全崩溃了吗?

该文件有什么特别之处吗?如果这不是问题,可以将其内容发布到pastebin吗?
Sergiy Kolodyazhnyy 2016年

另外,您的内存量是多少?您能否提供给我们输出free -h
Sergiy Kolodyazhnyy 2016年

要更改文件时,为什么要首先使用流编辑器?ex -sc '%s/original/edited/ge|x' file.log应该以UNIX惯用的方式完成您想要的操作而没有sed -i副作用。
David Ongaro '16

请注意,即使您正确执行了此操作(通过人们提供的任何方法),也可能会对属于活动进程的日志文件执行此类操作。
Random832'7

Answers:


10

就像已经说过的那样,>>追加到文件中,因此您的sed命令将坐在那里,读取刚输出的行,然后再输出一些行。如果您想就地替换文件,>仍然无法使用,但是您知道sed-i选项,这绝对是您想要的选项。

但是,如果您绝对确定要作为流附加到正在读取的文件上,并且只想进行一次传递,请考虑spongemoreutils包中使用。

sed 's/original/edited/g' file.log | sponge >> file.log

sponge从stdin读取到内存,直到EOF,然后将其所有内容转储到stdout,因此sed将命中文件的末尾,停止读取文件,将其关闭,然后海绵将开始附加到文件。


2
sponge是一个不错的实用工具,但是sed已经有一个-i选项:-i[SUFFIX], --in-place[=SUFFIX], edit files in place (makes backup if SUFFIX supplied)
约书亚·泰勒

@ JoshuaTaylor,OP正在使用>>,而不是>替换。诚然,OP -i在帖子中曾特别提到过,这似乎是比这更常见的用例,但我认为值得指出的是,OP发布的特定操作无需太多人手就能实现确保这是您想要做的。
ymbirtt '16

1
我在这里提到它是因为它是公认答案中的关键。这么说,我感到真正的快乐,了解海绵 ; 这是我工具箱的新工具,值得为此而赞扬。
约书亚·泰勒

1
啊! 我知道了。我将调整答案以使其更加清楚。另外,如果你喜欢sponge,就来看看vipemoreutils只是一个神奇的包裹,里面充满了您从来都不知道需要的东西
ymbirtt

18

您的sed命令试图读取要附加到的文件。它永远不会到达文件末尾,但是尝试会占用大量CPU时间。这就是发明^ C(中断电流过程)的原因。


我不认为^ C是那里的选择...它停止运行,即没有闪烁的光标被卡住!
EKons,2016年

18

在任何情况下,将其重新添加到您从中读取的文件都不是一个好主意,因为最终您将得到一个不断增长的文件。如果您确实要写回文件,则应使用-i标志:

sed -i 's/original/edited/g' file.log

或者,如果您希望它在进行更改之前创建备份,则可以将文件后缀添加到-i标志:

sed -i.bak 's/original/edited/g' file.log

这将创建一个名为的文件file.log.bak,然后进行更改,即通过尝试将其追加到您正在读取的文件中所做的操作,我们在程序员语中称为数据竞争,其中不同的进程竞争同一数据源的输入或输出。这也是您的机器停止运行的原因。


1
我很惊讶这是被接受的答案,因为它甚至都没有解决OP的问题"I really would like to understand why the execution of that command was able to make the system so unresponsive, and if mechanisms exist at the system level to trigger alerts and kill the offending process?"
Steve

@Steve关于我为什么停下来的原因,但是对于第二部分,您是正确的。我没有解决这个问题,因为我不知道答案。经过广泛的讨论之后,我们测试了该命令,并在不同的机器和操作系统上得出了完全不同的结果。示例:在具有Arch的计算机上,它只能使文件永久增长,而不会使计算机无响应。在我的Ubuntu计算机上,我得到的结果与发问者相同,而没有机会终止该过程。第二台在Ubuntu VM中进行相同测试的机器也停止了运行。
Videonauth

一个strace在另一边didtn的全过程,重现我的机器上和另一用户的机器上的结果,这一点。当然,有一种机制可以杀死无响应的应用程序,但是如果您的计算机无响应,则只有一个选项可以重置它。我仍在对此进行测试,在不完全了解导致上述行为的原因之前,我无法解决问题的这一部分。
Videonauth

内核配置可能有所不同,例如,对IO进行优先级排序的调度程序,或者系统之间的磁盘/文件系统驱动程序有所不同。很高兴看到你们进行了调查,这是很好的信息。
史蒂夫

如果您对另一个数据点感兴趣;我在文件很小的CentOS机器上尝试了此操作,它的功能与下面的海绵解决方案完全相同。我想对于一个小文件,它sed会将整个内容缓冲到内存中,然后关闭它,而不是保持句柄。与OP中一样,文件大小约为100MB,可以无限增长,但并不能使机器变砖。
ymbirtt '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.