-PIPE标志在kill命令中做了什么

jav*_*e42 1 unix shell scripting ksh kill-process

甲KornShell(KSH)脚本(scriptC.ksh)由间接调用scriptA.ksh(scriptA.ksh调用scriptB.ksh它调用scriptC.ksh).

scriptC.ksh:

kill -PIPE ${PPID} 
Run Code Online (Sandbox Code Playgroud)

什么是-PIPE标志在这里做?如果-管标志在使用scriptC.ksh那么这样的输出:

scriptA输出:

@:/tmp #ksh sciprtA.ksh
sciprtA.ksh[100]: 343434 Terminated
Terminated
Run Code Online (Sandbox Code Playgroud)

如果-PIPE删除,那么这是scriptC.ksh出口的终端输出:

scriptC.ksh:

kill ${PPID} 
Run Code Online (Sandbox Code Playgroud)

scriptA输出:

@:/tmp #ksh sciprtA.ksh
Terminated
Run Code Online (Sandbox Code Playgroud)

对此有何见解?

Nic*_*son 5

背景

kill -PIPE 告诉进程它正在写的东西已经退出,所以它也应该退出.

例如:

$ grep something file | more
Run Code Online (Sandbox Code Playgroud)

more进程停止读取时,grep将缓冲更多输出,但随后将被内核暂停,直到more再次开始读取(缓冲区的大小由内核确定).

假设文件中有很多匹配项; grep可以继续印刷线,直到奶牛回家,按需(只有几行将被缓冲,然后more读取它们,当缓冲区耗尽时,grep将再次唤醒以产生更多的输出).

但是,如果more提前退出(用户已经厌倦了读取线条),就没有必要grep继续吐出东西了.相反,它将被发送SIGPIPE说,"你的输出管已经消失了".默认操作SIGPIPE是终止.

所以,SIGPIPEUnix是一个奇怪的怪癖:在大多数平台上,如果你正在写一个文件并且出现错误,你会得到一个错误返回代码,就像任何其他失败一样(例如,在Windows上,例如,错误) for WriteFile由函数的返回码表示,就像那些DeleteFile或任何其他Win32函数一样).Unix是独一无二的,write因为应用程序以完全不同的方式处理错误,通过带外机制(信号处理程序)来处理任何其他系统调用的错误.这是因为管道是Unix命令行理念的核心,所以只要你写入任何你需要特殊行为的管道,当你的流的消费者消失时,它就会被预料到!

在你的例子中

在您的脚本中,您明确告诉进程终止,并且可选地执行任何清理,如果它在管道中,它将会执行.不幸的是,你没有给我们足够的背景来猜测你的脚本是用这种方式编写的(实际上包括脚本的相关部分可能解释了这个谜).在grep上面的示例中,发送SIGPIPEgrep将是导致more优雅退出的一种方式(如果grep退出SIGTERM,则可能需要父shell报告更严重的错误,具体取决于其实现如何监视管道).