Код Python для Perl
У меня есть кусок кода Python, который мне нужно преобразовать в Perl, но, к сожалению, я не очень хорош в Perl, поэтому извините, если вопрос прост. Я хотел бы проверить STDOUT и STDERR для конкретного слова. Вот код Python:
p = subprocess.Popen("bmod -b " + beginTime + " " + job_id + "; exit 1;",
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
while p.poll() is None:
err = p.stderr.readline().decode('utf_8')
out = p.stdout.readline().decode('utf_8')
if "changed" in err or "changed" in out:
subprocess.Popen("echo rescheduling was successful!", shell=True)
os._exit(0)
Я прочитал некоторые документы, и здесь может работать функция open3, но для части p.poll() я не уверен, что использовать.
1 ответ
Ответ зависит от того, важно ли напечатать сообщение "rescheduling was successful!"
сразу после того, как строка была напечатана из bmod
(когда bmod
все еще работает) или если достаточно напечатать строку после bmod
вышел.
Последний случай очень прост в Perl, например:
my $out = qx/bmod -b $beginTime $job_id 2>&1/;
say "rescheduling was successful!" if $out =~ /changed/;
Что касается первого случая, если вам нужно распечатать сообщение немедленно (даже до bmod
вышел), сначала обратите внимание, что ваш скрипт на Python, вероятно, работает неправильно. Линии p.stderr.readline()
будет блокировать скрипт, пока строка не будет готова для чтения из p.stderr
, так же p.stdout.readline()
будет блокировать скрипт, пока строка не будет готова для чтения из p.stdout
, Так что если bmod
печатает только stdout
и ничего не идет stderr
скрипт будет зависать при первом вызове p.stderr.readline()
и возвращаться только тогда, когда bmod
выходы.
Я не уверен, как это сделать правильно в Python, но в Perl вы можете использовать IPC::Open3
в сочетании с IO::Select
, Смотрите, например: Perl select return error "неверный дескриптор файла"
Также обратите внимание: более простое решение в Perl может быть достигнуто с помощью open
если stderr
а также stdout
объединены:
my $pid = open ( my $fh, '-|', "bmod -b $beginTime $job_id 2>&1" ) or die "Could not run command: $!";
while ( my $line = <$fh> ) {
print $line if $line =~ /changed/;
}
close $fh;