Как запустить скрипт и не ждать его в Perl? - PullRequest
7 голосов
/ 12 сентября 2011

У меня есть системный вызов в Perl, который выглядит следующим образом:

system('/path/to/utility >> /redirect/to/log file');

Но это ждет завершения utility.Я просто хочу вызвать это и позволить Perl-скрипту завершиться независимо от того, завершен вызов utility или нет.

Как я могу это сделать?

Я пыталсяизменив строку на

system('/path/to/utility >> /redirect/to/log file &');

, но этот синтаксис все еще ожидает завершения вызова в Windows.Мне нужно, чтобы он работал как в Linux, так и в Windows.

Ответы [ 4 ]

7 голосов
/ 12 сентября 2011
if ($^O eq 'MSWin32') {
   system('start "" \\path\\to\\utility >> \\redirect\\to\\log_file');
} else {
   system('/path/to/utility >> /redirect/to/log_file &');
}

или

if ($^O eq 'MSWin32') {
   system(1, '\\path\\to\\utility >> \\redirect\\to\\log_file');
} else {
   system('/path/to/utility >> /redirect/to/log_file &');
}
2 голосов
/ 12 сентября 2011

Эта общая задача была абстрагирована в модуль CPAN Proc::Background

2 голосов
/ 12 сентября 2011

Самый простой способ на POSIX-подобных системах - это тот, который вы уже пробовали:

system('/path/to/utility >> /redirect/to/log_file &');

Самый простой способ заставить инструмент работать в фоновом режиме в Windows - это использовать start.exe в качестве помощника для запуска:

system('start /path/to/utility >> /redirect/to/log_file');

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

Да, это означает, что вам потребуется ветвь кода в зависимости от текущей системы, но может понадобиться и другим решениям. Если ваш Perl имеет эмуляцию fork(), вы можете использовать fork() в обеих системах (это немного сложнее, поскольку вы не можете так просто перенаправить stdout в файл журнала, сначала вы должны открыть его в Perl и сделать его стандартный вывод разветвленного потомка перед вызовом нового процесса). Если ваш Windows Perl не имеет эмуляции fork(), вам также нужна ветвь кода, поскольку в этом случае вы можете использовать fork() только в UNIX и вам нужно будет использовать Win32::Process::Create с параметром DETACHED_PROCESS в Windows.

Но, может быть, вы сначала дадите нам знать, если использование start уже работает для вас. Если это не так, возможно start.exe не обрабатывает косые черты. В этом случае вам может понадобиться что-то вроде

C:\\path\\to\\utility

вместо этого (двойная обратная косая черта важна! Отдельная обратная косая черта имеет особое значение в строковых литералах; это escape-символ).

Чтобы выяснить, работаете ли вы в Windows или нет, взгляните на переменную $OSNAME или $^OS, в Windows она должна выглядеть примерно так: «MSWin32».

2 голосов
/ 12 сентября 2011

Вы можете попробовать поискать ключевое слово fork и запустить системную команду из разветвленного процесса.См. Справочную страницу perlipc.

...