这个'Broken Pipe`错误是否有解决方法?

时间:2018-02-10 21:43:32

标签: bash pipe

当我运行以下脚本时:

#!/bin/bash
cat /dev/urandom |  tr -dc '[:graph:]' | head -c 64

(应该打印64个随机字符,确实如此)

我得到以下输出:

Kn5Thh'H]F2NMG3^2(T*GdH]C+|Y0uj%C?LGFo=9d9o%vcP9k~6u~Q&exr`RuQv{./myScript: line 2: 21677 Broken Pipe             cat /dev/urandom
     21678                       | tr -dc '[:graph:]'
     21679 Done                    | head -c 64

为什么我收到Broken Pipe错误?是因为cat没有完成打印,但head已经完成,所以它会发送SIGPIPE

我该如何避免这种情况?

3 个答案:

答案 0 :(得分:4)

您实际上并不需要pipe,并且您不需要使用cat来打印/dev/urandom的输出这是一个非常糟糕的习惯,可能会产生不必要的进程和废物循环。

以下命令正常( bash ):

head -c64 <(tr -dc '[[:graph:]]' < /dev/urandom)

<强>输出:

$ head -c64 <(tr -dc '[[:graph:]]' < /dev/urandom)
\|_)gk$,gIW%vvBcc~B~:N2*FwozcdomgUI~I9$r$9Wj`q$KT4IoNI`)SS-i"Sc^

$ head -c64 <(tr -dc '[[:graph:]]' < /dev/urandom)                                                                                             
T8j0,?L))L4n@|(*EJ>Nkd|c7^t'[-7rnq8;E!sxIc>;SwOIhiPY"Zp}QWH&95nC

<强> READINGS:

https://www.ibm.com/developerworks/aix/library/au-badunixhabits.html#ten https://www.infoworld.com/article/2614499/unix/unix--when-pipes-don-t-make-sense.html https://superuser.com/questions/1059781/what-exactly-is-in-bash-and-in-zsh http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html

对于其他shell ,请使用:

tr -dc '[[:graph:]]' </dev/urandom | head -c64

答案 1 :(得分:4)

嗯,这种行为似乎取决于两个设置:

  1. 编译时选项git log -Sxxxx #search all commits git log -Sxxxx --branches[=<pattern>] #search branches 尚未在您的bash版本中设置(cf config-top.h)
  2. bash选项DONT_REPORT_SIGPIPE在您的环境中有效
  3. 尽管如此,您可以创建带括号的子shell,并将子shell的标准错误重定向到/ dev / null:

    set -o pipefail

    ---在最后一次编辑之前,这个答案看起来像这样:---

    (tr -dc '[[:graph:]]' </dev/urandom | head -c64) 2>/dev/null
    

答案 2 :(得分:0)

您对问题原因的诊断是正确的,一种简单的解决方法是使用 sed 代替 head:sed -n "1,10p" 等效于 head -n10。或者在您的特定情况下,这将匹配并打印标准输入中的前 64 个字符:

sed -rn "1s/(.{64}).*/\1/p"

-r 是一个 Gnu 扩展。没有它,看起来更复杂,但这只是因为必须转义特殊字符:

sed -n "1s/\(.\{64\}\).*/\1/p"

不同的系统可能需要不同的引号字符,例如' 而不是 ".