Сценарий оболочки c не завершается - PullRequest
0 голосов
/ 03 июля 2018

У меня есть Perl-скрипт, который вызывает скрипт оболочки c. что-то вроде

 system($cmd)

$ cmd содержит некоторый scirpt c-shell, который выполняет следующее:

some_task1 &
set task1_id = $!
sleep 300s &
set task2_id = $!

while (`ps -p "$task1_id,$task2_id" | wc -l` > 2)
     sleep 1m
end

# assume of the moment that task2 will finish first
kill -9 $task1_id 
exit

Я ожидаю, что процесс task1_id будет завершен и сценарий c-shell завершит работу и вернет управление вызывающему сценарию perl один раз

sleep 300s

сделано.

однако, что на самом деле происходит после того, как

exit 

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

Спасибо.

1 Ответ

0 голосов
/ 06 июля 2018

Таймаут

Один из способов возврата к вызывающему сценарию Perl - это вызов сценария csh в течение времени ожидания вызова. Компромисс в том, что сценарий csh будет прерван по истечении времени ожидания.

#!/usr/bin/env perl

use warnings FATAL => 'all';
use strict;
use Sys::SigAction qw(timeout_call);

my $cmd = 'sleep 5';
my $timeout = 2;
if (timeout_call($timeout, sub {
  my $out = system($cmd);
})) {
  print "command '$cmd' runs into timeout after $timeout s\n";
}

Тема

Другой подход заключается в инкапсуляции каждой задачи в системный вызов в потоке. Это очень простой пример, который не учитывает таймауты. Отдельные потоки будут жить после завершения сценария Perl и будут назначены PPID 1.

#!/usr/bin/env perl

use warnings FATAL => 'all';
use strict;
use threads;

my $task1 = threads->new(sub { 
  print "start task1\n"; qx(sleep 2); print "stop task1\n"; return 
});
my $task2 = threads->new(sub {
  print "task2\n"; qx(sleep 1); print "stop task2\n"; return 
});

$task2->join();
$task1->detach();
print "Detach task1\n";
...