【问题标题】:Shell script: get the exit status of a failed background child process in SolarisShell 脚本:获取 Solaris 中失败的后台子进程的退出状态
【发布时间】:2011-01-18 10:40:58
【问题描述】:

我写了一个 POC 。这段代码在 Linux 中运行良好,但在 Solaris 中不行。我正在使用 Solaris 10

enter code here
#!/bin/sh
echo inside parent
echo executing child in the background
./remove deepti & # executing dummy command to make sure that background process fails
childpid=$!
i=0
while [ `ps -p $childpid >/dev/null; echo $?` = 0 ]; do
    sleep 5
    i=`expr $i + 1`
    if [ $i -gt 3 ]; then
        echo wait exceeded
        ps -p $childpid >/dev/null
        exit $?
    fi
done
wait $childpid
exit $?

我希望 Wait 会返回后台命令的退出状态。退出状态应该是 127 。但是我的退出状态为 0。

【问题讨论】:

  • 格式正确的代码看不懂。
  • 如果我在这里输入代码 sn-p 那么默认情况下整个代码都在一个段落中。如何避免这种情况?
  • @userXXX:请将代码缩进四个空格,以便 StackOverflow 将其识别为要格式化的代码。我已经为您完成了,请阅读formatting help,了解有关人们想要回答的两个问题的详细信息:-)
  • 什么是“删除 deepti”?请提供可重现的案例。此外,您可以从代码示例中编辑掉“在此处输入代码”。
  • 你应该可以改变while [ ps -p $childpid >/dev/null; echo $?` = 0 ]` 到while ps -p $childpid >/dev/null(没有括号,反引号,echo)。

标签: shell solaris


【解决方案1】:

这不是错误,而是 /bin/sh 在 Solaris 上的预期和记录行为。引用自wait(1) manual page

如果 pid 不是活动进程 ID,则等待实用程序将立即返回,返回码将为 0。

较早的 Bourne shell 文档没有指定当调用已经死掉的进程时应该做什么等待,因此结果是未定义的行为。文档在 1998 年被修复以澄清这一点。ksh 是获得预期返回状态的推荐方法:http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4068875

对于 Solaris 10 及更早版本,/bin/sh 是一种旧版脚本语言,不应与新代码一起使用。您宁愿使用 /bin/ksh 或 /usr/xpg4/bin/sh 代替 POSIX 脚本。 Solaris 11 Express 提供了一个 POSIX /bin/sh,因此此类问题不会再发生。

【讨论】:

  • 非常感谢 /bin/sh 确实有问题。如果我使用 /bin/bash 或 /bin/ksh 代码可以完美运行。为了让它在 sh 上工作,我需要转到 /usr/xpg4/bin/sh 并将脚本中的第一行更改为 /usr/xpg4/bin/sh
  • @Deepti,这就是我告诉你的!
  • 看来你是 100% 正确的! (在 POSIX 和 this 上),当我错了时,我是第一个承认的人。
  • 谢谢。为什么不投票赞成我的回复呢?顺便说一句,由于您删除了答案,因此您的“这到底是什么”评论现在缺少上下文。
猜你喜欢
  • 2017-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
相关资源
最近更新 更多