【问题标题】:What does the -PIPE flag do in a kill command-PIPE 标志在 kill 命令中的作用
【发布时间】:2014-01-28 09:11:27
【问题描述】:

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

对此有何见解?

【问题讨论】:

  • 尝试man ksh 并查找描述kill 内置命令的部分。
  • @twalberg 在机器的本地手册页上没有运气......

标签: shell unix scripting ksh kill-process


【解决方案1】:

背景

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 正常退出的一种方式(如果grepSIGTERM 退出,则可能期望父shell 报告一个更严重的错误,具体取决于其实现如何监控管道)。

【讨论】:

  • +1,很好的答案。这是否也适用于磁盘已满且 echo "msg" | mail ... 之类的失败时? (你有 SIG 信息的来源(除了 man -s?signals(.h) 吗?)
  • 磁盘已满是一种不同于管道错误的写入错误——它只存在于常规文件中,而管道错误仅适用于管道!管道适用于具有大量数据的情况,例如 grep through / 可能需要数小时,因此在管道中的下一个进程结束后立即终止它很重要。
猜你喜欢
  • 2016-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多