Решение было очень простым. Мне просто нужно было добавить порт 8443 в список доступных портов Yast Firewall. На скриншоте это вкладка «Порты». После этого веб-приложение стало доступно из хост-ОС.
Хорошо, сначала несколько очевидных проблем. ${script_variables[@]}
заменяется на весь массив $script_variables
, разделенный пробелом. Таким образом, ваш test -z "${script_variables[@]}"
всегда будет ложным, поскольку вы определяете массив в начале скрипта, поэтому "${script_variables[@]}"
никогда не будет пустым. Когда вы хотите сослаться на элемент массива, вам нужно использовать определенный числовой индекс:"${script_variables[0]}"
для 1-го элемента, "${script_variables[1]}"
для второго и т. д.
Во-вторых, когда вы read
вводите значение в переменную, вам необходимо сохранить его в переменной. Однако вы даете read
расширенный массив, который представляет собой просто значения, хранящиеся в массиве:
$ echo "${script_variables[@]}"
admin_user_name admin_user_password
Что еще более важно, вы, кажется, хотите сохранить значение, которое дает пользователь, в переменной, которую затем можно вызвать по имени. Это, когда вы устанавливаете var="foo"
, а затем имеете variableName="var"
и пытаетесь получить значение переменной с именем var
(, поэтому «foo» в этом случае )называется «косвенным расширением». ". Синтаксис для этого ${!variableName}
. Например:
$ var="foo"
$ variableName="var"
$ echo "${!variableName}"
foo
Итак, вы можете использовать либо это, либо два массива :один для хранения имен переменных, а другой для хранения их значений. Или, что еще лучше в современных версиях bash, используйте единыйассоциативный массив , чьи ключи будут именами переменных. Вот рабочая версия вашего скрипта, использующая непрямое расширение:
#/bin/bash
script_variables=(
admin_user_name
admin_user_password
)
## This will be used to exit the loop
allSet="";
while [[ -z $allSet ]]; do
for varName in "${script_variables[@]}"; do
## No need to loop the whole thing, just loop
## until this particular variable has been set
while [[ -z ${!varName} ]]; do
read -p "Enter value for $varName: " $varName
done
done
## We will only exit the loop once all vars have been set.
## Now print and check them.
printf '\n=========\nYou have entered:\n'
for varName in "${script_variables[@]}"; do
printf '%s=%s\n' "$varName" "${!varName}"
done
while true; do
read -p "Are the variables correct? " yn
case $yn in
[Yy]* )
echo "All variables have been set. The script will now continue.";
## Setting this to 1 exits the top "while [[ -z $allSet ]]; do" loop
allSet=1
break;;
[Nn]* )
## Clear the stored values to start again
for varName in "${script_variables[@]}"; do
unset $varName
done
break;;
* )
echo "Please answer yes or no.";;
esac
done
done
А вот вариант с использованием ассоциативного массива:
#/bin/bash
declare -A script_variables=(
[admin_user_name]=""
[admin_user_password]=""
)
## This will be used to exit the loop
allSet="";
while [[ -z $allSet ]]; do
## '${!array[@]}' returns all keys of an associative array
for varName in "${!script_variables[@]}"; do
read -p "Enter value for $varName: " script_variables[$varName]
done
## We will only exit the loop once all vars have been set.
## Now print and check them.
printf '\n=========\nYou have entered:\n'
for varName in "${!script_variables[@]}"; do
printf '%s=%s\n' "$varName" "${script_variables[$varName]}"
done
while true; do
read -p "Are the variables correct? " yn
case $yn in
[Yy]* )
echo "All variables have been set. The script will now continue.";
## Setting this to 1 exits the top "while [[ -z $allSet ]]; do" loop
allSet=1
break;;
[Nn]* )
## Clear the stored values to start again
for varName in "${!script_variables[@]}"; do
script_variables[$varName]=""
done
break;;
* )
echo "Please answer yes or no.";;
esac
done
done
Лично я бы использовал несколько иной подход. Вместо того, чтобы настраивать все, а затем позволять пользователю проверять в конце, я бы проверял все по мере ввода. Таким образом, вы получаете ошибки в начале и вам не нужно -переустанавливать все переменные, а только ту, в которой вы ошиблись. Примерно так:
#/bin/bash
declare -A script_variables=(
[admin_user_name]=""
[admin_user_password]=""
)
allSet=0;
while [[ $allSet -lt ${#script_variables[@]} ]]; do
for varName in "${!script_variables[@]}"; do
ok=""
while [[ $ok != [Yy]* ]]; do
read -p "Enter value for $varName: " script_variables[$varName]
read -p "You entered '${script_variables[$varName]}'. Is this correct? " ok
done
## If we're satisfied, increment the value of allSet
((allSet++))
done
done
## You can add a second test here, but just exit the script if it's wrong.
## There's no point in complicating your code if you're just going back to
## the beginning anyway: just exit and rerun it.
printf '\n=========\nYou have entered:\n'
for varName in "${!script_variables[@]}"; do
printf '%s=%s\n' "$varName" "${script_variables[$varName]}"
done
read -p "Is everything OK? (y/n; n will exit the script)": yn
if [[ $yn != [Yy]* ]]; then
exit
fi
echo "Everything correctly set, continuing!"