为什么这些代码在各种发行版/ Unix中表现不同?

时间:2011-07-21 08:49:24

标签: python unix shell subprocess signals

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

在其中一些(例如Debian stable)中,C app获取信号, 消息从信号处理程序和脚本打印得很好 饰面。在其他人(例如两年前的Ubuntu和OpenBSD) 信号丢失,因此根本不打印信息, 并且脚本永远等待......

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

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

进入这个...

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

所以看来在某些Unix中,中间shell“吃掉”了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()

3 个答案:

答案 0 :(得分:6)

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

/bin/sh几乎总是一个象征性链接形式的别名:真正的shell可以是busybox,bash,ash,csh,ksh,dash,zsh,tcsh或者疯狂的东西(呃)。< / p>

确认您实际上在所有系统上使用相同的shell,然后如果问题是特定的shell,您知道在哪里查找有关它的行为的更多信息。

答案 1 :(得分:2)

如果您将信号发送到流程组,它也可以使用短划线:How to terminate a python subprocess launched with shell=True

答案 2 :(得分:0)

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

相关问题