Как получить PID программы, выполняемой в скрипте Perl - PullRequest
0 голосов
/ 22 декабря 2018

Этот ответ объясняет, как получить pid нового процесса при использовании Perl exec().Pid даже не меняется, поэтому все, что вам нужно сделать, это получить pid оригинального скрипта.Но это не сработает, если я перенаправлю вывод в файл как часть команды, что мне нужно сделать.

say "my pid is $$";
exec("childscript.pl");                  # same pid

Но если я перенаправлю вывод как часть команды:

say "my pid is $$";
exec("childscript.pl > log.txt");        # different pid, usually old pid + 1
exec("childscript.pl > log.txt 2>&1 &"); # same

, тогда новый pid будет на один выше, чем старый (что, вероятно, только потому, что они были созданыпо очереди и не надежно).Я проверил это как путем просмотра выходных данных, так и путем вставки sleep 30 в «childscript.pl», чтобы я мог видеть его с помощью ps -e.

Я предполагаю, что перенаправление вывода вызываетновый процесс, чтобы сделать написание.Но мне нужен pid программы, и я не имею никакого контроля над программой, за исключением того факта, что я могу ее выполнить.(Он также должен работать в фоновом режиме.)

1 Ответ

0 голосов
/ 22 декабря 2018

Когда вы вызываете exec с одним аргументом (и этот аргумент содержит метасимволы оболочки), perl автоматически запускает sh -c ARG для вас.В вашем случае:

exec("childscript.pl > log.txt");
# really means:
exec("/bin/sh", "-c", "childscript.pl > log.txt");

Т.е. ваш скрипт загружает sh в текущий запущенный процесс, сохраняя свой PID.Оболочка выполняет перенаправление вывода, затем запускает childscript.pl как дочерний процесс (с новым PID).

Существует два способа решения этой проблемы:

  1. Выполнитьперенаправление вывода в Perl и не вызывать оболочку:

    open STDOUT, ">", "log.txt" or die "$0: log.txt: $!\n";
    exec "childscript.pl";
    die "$0: childscript.pl: $!\n";
    
  2. Скажите оболочке также использовать exec и не создавать дочерний процесс:

    exec "exec childscript.pl > log.txt";
    die "$0: childscript.pl: $!\n";
    
...