Команда Perl в bash-скрипте не интерпретирует команду (буквально подставляет ее) - PullRequest
1 голос
/ 12 июня 2019

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

#/bin/bash

display_usage() {
        echo -e "\nUsage: This script must be run with an environment parameter (file in directory env/)."
        echo -e "Example: ./configureEnv <env parameter>\n"
        }

# If no env argument supplied, display usage.
if [  $# -eq 0 ]; then
        display_usage
        exit 1
fi

# Replace the placeholder of FIREBASE_ENV in index.html with the Firebase env settings.
perl -pi -e 's/%FIREBASE_ENV%/`cat testEnvConfig`/g;' index.html

if [ $? -eq 0 ]; then
   echo "Updated Firebase settings based on environment file: $1"
   exit 0
else
    echo "[Error] Environment settings configuration failed. Please check parameters are correct."
    exit 1
fi

Как видите, ключевая строка:

perl -pi -e 's/%FIREBASE_ENV%/`cat testEnvConfig`/g;' index.html

Он должен заменить строку заполнителя% FIREBASE_ENV% содержимым файла, но вместо этого он заменяет% FIREBASE_ENV% на `cat testEnvConfig`.

Ответы [ 3 ]

2 голосов
/ 12 июня 2019

Замена в подстановке интерполирует переменные, такие как двойные кавычки, но не интерпретирует обратные пометки.Вам нужно указать модификатор /e, чтобы оценить замену как код.Perl может читать файл и сохранять его содержимое в переменной:

my $config = do { local( @ARGV, $/ ) = 'testEnvConfig'; <> };
# ...
s/%FIREBASE_ENV%/$config/g;
2 голосов
/ 12 июня 2019

С (очень полезным) модулем Perl Path :: Tiny чтение файла занимает одно утверждение, и у нас есть

perl -MPath::Tiny -i.bak -pe'
    BEGIN { $f = path("testEnvConfig")->slurp; chomp $f }; 
    s/%FIREBASE_ENV%/$f/g
' index.html

Я добавил резервную копию .bak для вашегобезопасность при тестировании и разделение кода на строки для удобства чтения.

Я удаляю последнюю строку из файла.Если вы действительно хотите, чтобы это было удалено, то chomp $f


Почему ваша честная попытка не сработала, объяснено, так как вам нужно оценить заменяющую деталь как код с помощью /e.Однако, как только вы это сделаете, посмотрите на ситуацию:

  • из скрипта bash вызовите Perl-программу (однострочник)

  • который выходит в систему (по крайней мере, системный вызов, возможно, еще одна оболочка!)

  • , где запускается еще одна программа (cat)

  • с содержимым файла, отправленным обратно в Perl, который затем делает свое дело.

Да.Лучше просто прочитать этот файл на Perl, нет?

1 голос
/ 12 июня 2019

По умолчанию правая часть подстановки (s///) работает как строка в двойных кавычках. "`cat whatever`" не делает ничего особенного в строке; он не запускает никаких команд.

Вам необходимо использовать флаг /e:

s/%FIREBASE_ENV%/`cat testEnvConfig`/eg

Это говорит Perl, что правая часть должна быть оценена как блок кода, а не как строка.

В качестве альтернативы вы можете избежать вывода на cat, читая файл в Perl:

perl -pi -e 'BEGIN { my $file = "testEnvConfig"; open my $fh, "<", $file or die "$file: $!\n"; local $/; $config = readline $fh } s/%FIREBASE_ENV%/$config/g'

Это также позволяет избежать повторного чтения файла для каждого вхождения %FIREBASE_ENV%.

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