Почему этот код ведет себя по-разному в разных дистрибутивах / Unix? - PullRequest
2 голосов
/ 21 июля 2011

Следующее (небольшая программа на C и вызывающий ее скрипт на python) ведут себя по-разному в разных Unixes.

В некоторых из них (например, в стабильной версии Debian) приложение C получает сигнал, сообщение печатается нормально из обработчика сигнала и сценарий завершается.В других (например, двухлетняя Ubuntu и OpenBSD) сигнал теряется, и поэтому сообщение вообще не печатается, а сценарий ждет вечно ...

Сигнал доставляется ВСЕГДА, еслив скрипте Python я изменяю это ...

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

на это ...

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

Так что получается, что в некоторых Unix-системах промежуточная оболочка "съедает" SIGINT,в то время как в других он перенаправляет его в дочерний процесс (программу на C).

Я позаботился о том, чтобы вызывать только входящие функции в обработчике сигналов, так что это, похоже, не связано с моим кодом C -похоже, что поведение обработки сигналов в "/ bin / sh" (оболочке по умолчанию, используемой Python для порождения вещей) не является "стабильным" в Unixes ...

Я что-то не так делаю?

РЕДАКТИРОВАТЬ: В случае, если вам интересно, почему я использовал «shell = True»: это потому, что в моем реальном коде я не просто передаю «./executable» - я использую код оболочки для циклови подстановочные знаки.

Это код C, который печатается и умирает, когдаон получает SIGINT:

#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);
}

И это скрипт Python, который проверяет его, отправляя SIGINT:

#!/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 ]

6 голосов
/ 21 июля 2011

То, что Python использует /bin/sh, не означает, что это одинаковая оболочка во всех системах.

/bin/sh почти всегда является псевдонимом в виде символической ссылки: настоящей оболочкой может быть busybox, bash, ash, csh, ksh, dash, zsh, tcsh или что-то сумасшедшее (er).

Подтвердите, что вы на самом деле используете одну и ту же оболочку во всех системах, а затем, если проблема связана с конкретной оболочкой, вы знаете, где искать дополнительную информацию о ее поведении.

2 голосов
/ 21 июля 2011

Он также будет работать с дефисом, если вы отправите сигнал группе процессов: Как завершить подпроцесс python, запущенный с shell = True

0 голосов
/ 21 июля 2011

Хорошо бы убедиться, что ваш скрипт POSIX-совместим.У меня была проблема с переносом BASH-скрипта на DASH.Я просто изменил части скрипта bash, относящиеся к BASH, и заменил их на POSIX-совместимый синтаксис.

...