KornShell(ksh)脚本( scriptC.ksh )由 scriptA.ksh 间接调用( scriptA.ksh 调用 scriptB.ksh ,它调用 scriptC.ksh )。
的 scriptC.ksh: 的
kill -PIPE ${PPID}
-PIPE
旗帜在这里做什么?如果在 scriptC.ksh 中使用了-PIPE标志,那么这就是输出:
scriptA输出:
@:/tmp #ksh sciprtA.ksh
sciprtA.ksh[100]: 343434 Terminated
Terminated
如果-PIPE
被删除,则这是 scriptC.ksh 退出的终端输出。:
的 scriptC.ksh: 的
kill ${PPID}
scriptA输出:
@:/tmp #ksh sciprtA.ksh
Terminated
对此有何见解?
答案 0 :(得分:5)
kill -PIPE
告诉进程它写入的内容已经退出,所以它也应该退出。
例如:
$ grep something file | more
当more
进程停止读取时,grep
将缓冲更多输出,但内核将暂停,直到more
再次开始读取(缓冲区的大小)由内核确定。
假设文件中有很多匹配项; grep
可以继续打印行,直到奶牛回家,按需(只有几行会被缓冲,然后more
读取它们,当缓冲区耗尽时,grep
将是再次醒来以产生更多的输出)。
但是,如果more
提前退出(用户已经厌倦了阅读这些行),那么grep
就没有必要继续吐出东西了。相反,它将被发送SIGPIPE
说,“你的输出管已经消失了”。 SIGPIPE
上的默认操作是终止。
所以,SIGPIPE
是Unix的一个奇怪的怪癖:在大多数平台上,如果你正在写一个文件并且出现错误,你会得到一个错误返回代码,它就像任何其他失败一样(那个例如,在Windows上,WriteFile
的错误由函数的返回码指示,就像DeleteFile
或任何其他Win32函数的错误一样。 Unix是独一无二的,因为write
的错误由应用程序通过带外机制(信号处理程序)以完全不同的方式处理任何其他系统调用的错误。那是因为管道是Unix命令行理念的核心所在,所以只要你写入任何你需要特殊行为的管道,当你的流的消费者消失时,它就会被预料到!
在您的脚本中,您明确告诉进程终止,并且可选地执行它在管道中期望执行的任何清理。不幸的是,你没有给我们足够的背景来猜测你的脚本是用这种方式编写的(实际上包括脚本的相关部分可能解释了这个谜)。在上面有grep
的示例中,将SIGPIPE
发送到grep
会导致more
正常退出(如果grep
退出{{1}可能需要父shell报告更严重的错误,具体取决于其实现监视管道的方式。)