Процесс выхода начался в Perl - PullRequest
1 голос
/ 08 декабря 2011

Привет, как я смогу выйти из завершившегося процесса, который был запущен с использованием qx // в perl на машине с Linux?

Я думал о вызове ps, чтобы найти PID и вызвать kill toвыход.Но мне было интересно, есть ли более простой способ сделать это.

Спасибо

Ответы [ 3 ]

4 голосов
/ 08 декабря 2011

Если он был запущен с qx// и закончил, убивать его не нужно, его уже нет. Я подозреваю, что вы действительно застряли: не закончил процесс, но больше ничего не делал для вас.

Вы ничего не можете сделать напрямую со стороны Perl. qx// - синхронный вызов. Он ожидает, что процесс, который он запускает, завершается, и его единственным кодом возврата является дамп STDOUT процесса. (незначительно, также его код возврата через $?)

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

Так что в вашем случае, если это проблема с одним выстрелом, вам просто нужно найти и завершить неисправный процесс с помощью любой комбинации ps, grep, kill, pgrep, pkill лучше всего подходит для вашего мышления. Если это повторяющаяся проблема, вы должны перейти от встроенного средства qx// к тому, что даст вам лучший контроль. Например, IPC :: Run предоставляет тайм-ауты.

3 голосов
/ 08 декабря 2011

Я думаю, что реальный вопрос, который вы хотите задать, это «Как запустить процесс в фоновом режиме (и, возможно, убить его позже)?»

Самое простое решение - open труба из процесса.Так что вместо

my $output = qx/some_command/;
# do something with $output

вы бы сделали

my $pid = open my $pipe, "some_command |"  or die $!;
while (my $line = <$pipe>) {
    # do something with $line
    last if some_condition();
}
close $pipe  or $! and die $!;

Если вы close передадите канал до завершения дочернего процесса, то при следующей попыткечтобы вывести что-то, он получит сигнал SIGPIPE, который обычно его убивает.Если вы подозреваете, что процесс может продолжать работать без вывода какого-либо результата, вы можете kill вручную, например,

kill $pid, 1;  # 1 == SIGHUP on most Unix systems

(Вы должны сделать это до закрытия канала, так как close будет ожидать завершения процесса.)

Однако учтите, что если Perl должен был вызывать оболочку для анализа вашей команды, идентификатор процесса, возвращаемыйopen будет оболочкой, а не самой командой.Вы можете избежать этого, используя форму с несколькими аргументами open:

my $pid = open my $pipe, '-|', $command, @command_args  or die $!;
1 голос
/ 08 декабря 2011

Вы можете использовать

pkill -o -u urbanspr1nter -f some_command

или pgrep ... | xargs ps вместо pkill, чтобы сначала просмотреть его.

...