Как использовать синтаксис bash в системе Perl()?
Как я могу использовать синтаксис bash
в команде Perl system()
?
У меня есть команда bash -специфическая, например. следующее, использующее bash замену процесса:
diff <(ls -l) <(ls -al)
Я хотел бы назвать это из Perl, используя
system("diff <(ls -l) <(ls -al)")
но это дает мне ошибку, потому что вместо bash
используется sh
для выполнения команды:
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `sort <(ls)'
Ответы
Ответ 1
Скажите Perl для прямого вызова bash. Используйте list
вариант system()
, чтобы уменьшить сложность вашего цитирования:
my @args = ( "bash", "-c", "diff <(ls -l) <(ls -al)" );
system(@args);
Вы даже можете определить подпрограмму, если вы планируете делать это достаточно часто:
sub system_bash {
my @args = ( "bash", "-c", shift );
system(@args);
}
system_bash('echo $SHELL');
system_bash('diff <(ls -l) <(ls -al)');
Ответ 2
system("bash -c 'diff <(ls -l) <(ls -al)'")
должен сделать это теоретически. Bash -c
позволяет вам передать команду оболочки для выполнения, в соответствии с man-страницей.
Ответ 3
Проблема с ответами vladr заключается в том, что система не будет выводить вывод в STDOUT из команды (которую вы обычно хотели бы), а также не позволяет выполнять более одной команды (учитывая использование сдвига, а не доступ к полному содержимому @_).
Что-то вроде следующего может быть больше подходит для проблемы:
my @cmd = ( 'diff <(ls -l) <(ls -al)', 'grep fu' );
my @stdout = exec_cmd( @cmd );
print join( "\n", @stdout );
sub exec_cmd
{
my $cmd_str = join( ' | ', @_ );
my @result = qx( bash -c '$cmd_str' );
die "Failed to exec $cmd_str: $!" unless( $? == 0 && @result );
return @result;
}
К сожалению, это не помешает вам вызвать /bin/sh только для запуска bash, однако я не вижу обходного пути для этой проблемы.
Ответ 4
Я предпочитаю выполнять команды bash в perl с обратными выводами "`". Таким образом, я получаю возвращаемое значение, например:
my $value = \`ls`;
Кроме того, мне не нужно использовать "bash -c", чтобы запустить commmand. Работает для меня.
Ответ 5
Вдохновленный ответом от @errant.info, я создал что-то более простое и работал у меня:
my $line="blastn -subject <(echo -e \"$seq1\") -query <(echo -e \"$seq2\") -outfmt 6";
my $result=qx(bash -c '$line');
print "$result\n";
Введенная переменная $line позволяет изменять входы ($ seq1 и $seq2) каждый раз.
Надеюсь, это поможет!