Jas*_*ltz 43 bash ruby .bash-profile rvm
我最近在获得 SSD 驱动器后重新安装了 Ubuntu 12.10 后重新安装了 RVM(按照http://rvm.io 上的说明进行操作)。
现在,当我输入: type rvm | head -1
我收到以下错误:
rvm is a function
-bash: type: write error: Broken pipe
Run Code Online (Sandbox Code Playgroud)
但是,如果我立即重复该命令,那么我只会收到:
rvm is a function
Run Code Online (Sandbox Code Playgroud)
而且看起来一切正常?发生了什么?我能做些什么来修复它?它并不总是发生。它似乎更加零星。我试图找到某种模式,但还没有。
use*_*686 62
在这种情况下看到“断管”很少见,但很正常。
当您运行 时type rvm | head -1
,bashtype rvm
在一个进程head -1
中执行,在另一个进程中执行。1的标准输出type
连接到管道的“写”端,标准输入head
连接到“读”端。两个进程同时运行。
该head -1
进程从 stdin 读取数据(通常以 8 kB 的块为单位),打印出一行(根据-1
选项),然后退出,导致管道的“读取”端关闭。由于该rvm
函数很长(在被 bash 解析和重构后大约 11 kB),这意味着head
退出时type
还有几 kB 的数据要写出。
此时,由于type
正在尝试写入另一端已关闭的管道 -损坏的管道 - 它调用的 write() 函数将返回一个 EPIPE 错误,翻译为“损坏的管道”。除了这个错误之外,内核还会向 发送 SIGPIPE 信号type
,默认情况下它会立即终止进程。
(该信号在交互式 shell 中非常有用,因为大多数用户不希望第一个进程继续运行并试图无处写入。同时,非交互式服务会忽略 SIGPIPE – 这对于长时间运行的守护进程来说是不利的死于这样一个简单的错误——所以他们发现错误代码非常有用。)
但是,信号传递不是 100% 立即传递的,并且可能存在 write() 返回 EPIPE 并且进程在接收信号之前继续运行一小段时间的情况。在这种情况下,type
在被 SIGPIPE 杀死之前,有足够的时间注意到失败的写入,转换错误代码,甚至将错误消息打印到 stderr。(错误消息说“-bash:type:”因为type
是bash本身的内置命令。)
这在多 CPU 系统上似乎更常见,因为type
进程和内核的信号传递代码可以在不同的内核上运行,实际上是同时运行的。
可以通过修补type
内置(在 bash 的源代码中)以在它从 write() 函数接收到 EPIPE 时立即退出来删除此消息。
但是,这没有什么可担心的,它与您的rvm
安装没有任何关系。
Huu*_*uuu 28
您可以通过插入管道以牺牲另一个进程为代价来修复损坏tail -n +1
的管道,如下所示:
类型 rvm | 尾 -n +1 | 头-1
该+1
通知tail
打印输入和遵循事物的第一道防线。输出将与tail -n +1
不存在时完全相同,但该程序足够智能,可以检查标准输出并干净地关闭管道。不再有破损的管道。
小智 9
让我们尝试一下yes
,无限的流程打印是的......
之前,yes
进程在达到限制时会被 SIGPIPE 终止。
\xe2\x9e\x9c set -o pipefail\n\xe2\x9e\x9c yes | head -n 1\ny\n\xe2\x9e\x9c echo $? \n141\n
Run Code Online (Sandbox Code Playgroud)\n\n我的解决方案
\n\n\xe2\x9e\x9c yes | (head -n 1;dd status=none of=/dev/null)\ny\n\n\n# the process will still running and output to null\n
Run Code Online (Sandbox Code Playgroud)\n\n你可以yes
用你的程序替换。
归档时间: |
|
查看次数: |
148336 次 |
最近记录: |