#bash #loops #sed
#bash #циклы #sed
Вопрос:
Есть какой bash
-то скрипт, который содержит два массива:
names=( [0]=port_shutdown
[1]=port_http
[2]=port_https
[3]=keystore_file
[4]=key_alias
[5]=keystore_pass
[6]=truststore_file
[7]=truststore_pass )
value=( [0]="$port_shutdown"
[1]="$port_http"
[2]="$port_https"
[3]="$keystore_file"
[4]="$key_alias"
[5]="$keystore_pass"
[6]="$truststore_file"
[7]="$truststore_pass" )
И переменные:
port_shutdown="8008"
port_http="8046"
port_https="8446"
keystore_file="tomcat.jks"
key_alias="tomcat"
keystore_pass="password"
truststore_file="trustcacerts.jks"
truststore_pass="password"
Запустите его в цикле:
while [ "$i" -lt "11" ]; do
name="${names[${i}]}"
value="${value[${i}]}"
echo -e "Changing name - "$name" to value "$value";n"
sed 's|'"${name}"'|'"${value}"'|g' "server.xml.default" > "server.xml"
(( i ))
done
Но это не меняется names
… Хотя — он видит значения в переменных:
$ ./config.sh
Changing name - port_shutdown to value "8008";
Changing name - port_http to value 8046;
Changing name - port_https to value 8446;
Changing name - keystore_file to value tomcat.jks;
Changing name - key_alias to value tomcat;
Changing name - keystore_pass to value password;
Changing name - truststore_file to value trustcacerts.jks;
Changing name - truststore_pass to value password;
Если я задам, например name="port_shutdown"
, и value="8008"
— это работает хорошо…
Что я здесь делаю не так?
Комментарии:
1. Это выглядит действительно неудобно :
value="${value[${i}]}"
. Это установило значение нулевого поля массиваvalue
в расширение${value[${i}]}
. Конечно, не то, что вы хотите (но без нежелательных эффектов в вашем фрагменте).
Ответ №1:
попробуйте, может быть
sed "s|${name}|${value}|g" "server.xml.default" > "server.xml"
но он неправильно указывает что-то как разделитель (например: port_http
также изменится port_https
, если имя массива будет в этом порядке)
Комментарии:
1. Да, это так, это исправит. Спасибо за замечание.
Ответ №2:
Извините, ребята…
Давайте посмотрим, что происходит с sed
этим loop
:
sed 's|'"${name}"'|'"${value}"'|g' "server.xml.default" > "server.xml"
Итак, он занимает ПЕРВОЕ $name
и ПЕРВОЕ $value
МЕСТО, берет содержимое server.xml.default
, ищет вхождения (совпадения?) в нем замените его, сохраните в файл server.xml
. Все в порядке.
Но в следующем цикле — он берет СТАРОЕ server.xml.default
, ищет ВТОРОЕ $name
и ВТОРОЕ $value
, и… Сделайте то же самое — но в новом server.xml
он сохранит действие ВТОРОГО цикла, но действие ПЕРВОГО цикла останется неизмененным.
Итак, решение состояло в том, чтобы создать временный файл, который будет сохранять все изменения после каждого цикла:
i=0
cp server.xml.default server.xml.tmp
while [ "$i" -lt "11" ]; do
name="${names[${i}]}"
value="${value[${i}]}"
echo -e "Changing name - "$name" to value "$value";n"
sed 's|'"${name}"'|'"${value}"'|g' server.xml.tmp > server.xml
cp server.xml server.xml.tmp
(( i ))
name=
value=
done