【问题标题】:Why is this code behaving differently across various distros/Unixes?为什么这段代码在不同的发行版/Unix 上表现不同?
【发布时间】:2011-10-10 01:10:33
【问题描述】:

以下(一个小的C程序和一个调用它的python脚本) 在不同的 Unix 上表现不同。

在其中一些(例如 Debian stable)中,C 应用程序会收到信号, 从信号处理程序和脚本中可以很好地打印消息 完成。在其他情况下(例如两岁的 Ubuntu 和 OpenBSD) 信号丢失,因此根本不打印消息, 并且脚本永远等待......

信号总是被传递,如果在 python 脚本中,我改变这个...

mysub=subprocess.Popen("./cryInAbort", shell=True)

进入这个...

mysub=subprocess.Popen("./cryInAbort", shell=False)

因此,在某些 Unix 中,中间外壳似乎“吃掉”了 SIGINT, 而在其他情况下,它会将其转发给子进程(C 程序)。

我注意只在信号处理程序中调用可重入函数 所以这似乎与我的 C 代码无关 - 看起来好像 "/bin/sh" 中的信号处理行为(使用的默认 shell 由 Python 产生的东西)在 Unix 上不是“稳定的”......

我做错了吗?

编辑:如果您想知道为什么我使用“shell=True”:这是因为在我的真实代码中,我不只是传递“./executable” - 我正在使用 shell 代码循环和通配符。

这是得到 SIGINT 时打印并死掉的 C 代码:

#include <signal.h>
#include <unistd.h>

void my_handler()
{
    static const char msg[] = "Goodbye - test was OK.\n";
    write(1,msg,sizeof(msg));
    fsync(1);
    _exit (0);
}

int main()
{
    (void) signal (SIGINT, my_handler);
    while (1);
}

这是通过发送 SIGINT 来测试它的 Python 脚本:

#!/usr/bin/env python
import subprocess,signal,time
mysub=subprocess.Popen("./cryInAbort", shell=True)
time.sleep(2)
mysub.send_signal(signal.SIGINT)
mysub.wait()

【问题讨论】:

    标签: python unix shell subprocess signals


    【解决方案1】:

    仅仅因为 Python 使用 /bin/sh 并不意味着它在所有系统上都是相同的 shell。

    /bin/sh 几乎总是符号链接形式的别名:真正的 shell 可能是busybox、bash、ash、csh、ksh、dash、zsh、tcsh 或其他一些疯狂的东西。

    确认您实际上在所有系统上都使用相同的 shell,然后如果问题出在某个特定的 shell,您就知道在哪里可以找到有关其行为的更多信息。

    【讨论】:

    • 已验证 - Ubuntu 使用的是 dash,OpenBSD 使用的是 ksh。将 /bin/sh 切换为指向 bash 的符号链接使 OpenBSD 像 Debian 一样工作。谢谢。
    • 如果它可以帮助其他人:调用 Popen 时,可以指定使用哪个 shell,其中:mysub=subprocess.Popen("./cryInAbort", shell=True, executable="/bin /bash")
    【解决方案2】:

    确保您的脚本符合 POSIX 标准是一件好事。我在将 BASH 脚本移植到 DASH 时遇到了这个问题。我只是更改了 bash 脚本中特定于 BASH 的部分,并将它们替换为符合 POSIX 的语法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-23
      • 2019-08-14
      • 1970-01-01
      • 2015-04-04
      相关资源
      最近更新 更多