Как я могу использовать синтаксис bash в системе Perl ()? - PullRequest
14 голосов
/ 21 февраля 2009

Как использовать синтаксис bash в команде Perl system()?

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

 diff <(ls -l) <(ls -al)

Я хотел бы вызвать его из Perl, используя

 system("diff <(ls -l) <(ls -al)")

но выдает ошибку, потому что для выполнения команды используется sh вместо bash:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `sort <(ls)'

Ответы [ 5 ]

46 голосов
/ 21 февраля 2009

Скажите 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)');
6 голосов
/ 21 февраля 2009
 system("bash -c 'diff <(ls -l) <(ls -al)'")

должен сделать это, теоретически. Опция Bash -c позволяет передавать команду оболочки для выполнения в соответствии со страницей руководства.

4 голосов
/ 29 августа 2012

Проблема с ответами vladr состоит в том, что система не будет захватывать вывод в STDOUT из команды (которую вы обычно хотели бы), а также не позволяет выполнять более одной команды (учитывая использование shift вместо доступ к полному содержанию @_).

Что-то вроде следующего может быть более подходящим для этой проблемы:

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, однако я не вижу обходного пути для этой проблемы.

0 голосов
/ 19 февраля 2017

Вдохновленный ответом @ 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). Надеюсь, это поможет!

0 голосов
/ 18 декабря 2012

Я предпочитаю выполнять команды bash в perl с обратными галочками "` ". Таким образом, я получаю возвращаемое значение, например:

my $value = \`ls`;

Кроме того, мне не нужно использовать "bash -c" только для запуска команды. У меня работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...