Backlics Perl: используйте Bash вместо Sh - PullRequest
6 голосов
/ 30 июля 2010

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

Как мне изменить это поведение, чтобы perl использовал bash?

PS.Команда, которую я пытаюсь запустить:

paste filename <(cut -d \" \" -f 2 filename2 | grep -v mean) >> filename3

Ответы [ 6 ]

7 голосов
/ 30 июля 2010

Попробуйте

`bash -c \"your command with args\"`

Я вполне уверен, что аргумент -c интерпретируется так, как bash интерпретирует свою командную строку. Хитрость в том, чтобы защитить его от sh - вот для чего нужны кавычки.

7 голосов
/ 30 июля 2010

«Системная оболочка» обычно не изменчива.См. perldoc -f exec :

Если в LIST имеется более одного аргумента или если LIST является массивом с более чем одним значением, вызывает execvp (3) саргументы в СПИСОК.Если есть только один скалярный аргумент или массив с одним элементом, этот аргумент проверяется на наличие метасимволов оболочки, и, если они есть, весь аргумент передается командной оболочке системы для анализа (это "/bin / sh -c "на платформах Unix, но различается на других платформах.)

Если вам действительно нужен bash для выполнения конкретной задачи, рассмотрите возможность ее явного вызова:

my $result = `/usr/bin/bash command arguments`;

или даже:

open my $bash_handle, '| /usr/bin/bash' or die "Cannot open bash: $!";
print $bash_handle 'command arguments';

Вы также можете поместить свои команды bash в файл .sh и вызвать их напрямую:

my $result = `/usr/bin/bash script.pl`;
5 голосов
/ 30 июля 2010

Этот пример работает для меня:

$ perl -e 'print `/bin/bash -c "echo <(pwd)"`'
/dev/fd/63
1 голос
/ 09 декабря 2014

Чтобы справиться с запуском bash и вложенных кавычек, эта статья предлагает лучшее решение: Как использовать синтаксис bash в системе Perl ()?

my @args = ( "bash", "-c", "diff <(ls -l) <(ls -al)" );
system(@args);
0 голосов
/ 05 сентября 2013

Создать подпрограмму perl:

sub bash { return `cat << 'EOF' | /bin/bash\n$_[0]\nEOF\n`; }

И использовать ее, как показано ниже:

my $bash_cmd = 'paste filename <(cut -d " " -f 2 filename2 | grep -v mean) >> filename3';
print &bash($bash_cmd);

Или использовать perl here-doc для многострочных команд:

$bash_cmd = <<'EOF';
    for (( i = 0; i < 10; i++ )); do
       echo "${i}"
    done
EOF
print &bash($bash_cmd);
0 голосов
/ 30 июля 2010

Я думал, что perl будет учитывать переменную $SHELL, но потом мне пришло в голову, что ее поведение на самом деле может зависеть от реализации exec вашей системы. В моем, кажется, что exec

выполнит оболочку (/ bin / sh) с путем файл в качестве первого аргумента.

Вы всегда можете сделать qw/bash your-command/, нет?

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