Вопрос или проблема
У меня есть конвейер, который развертывает скрипты во временную директорию. Мне нужно переместить их в их фактическую правильную директорию.
#!/usr/bin/sh
DEPLOY_HOME=/opt/xxx
function getDeployedFiles {
ls ${DEPLOY_HOME} | grep -v pipeline.properties | grep -v Deploy.tmp >
${DEPLOY_HOME}/Deploy.tmp
chmod 700 ${DEPLOY_HOME}/Deploy.tmp
readarray -t depFilesArr < ${DEPLOY_HOME}/Deploy.tmp
}
function setDict {
declare -A dict
dict=(
["a.script.100"]="/opt/xxx/firstpath/100"
["b.script.200"]="/opt/xxx/secondpath/200"
["c.script.300"]="/opt/xxx/thirdpath/300"
)
}
function itArr {
for i in "${depFilesArr[@]}"; do
FILENAME="${i}"
if [[ -v "${dict['${i}']}" ]]; then
echo "Значение присутствует"
FILEDEST="${dict['${i}']}"
mv ${DEPLOY_HOME}/${FILENAME} ${FILEDEST}/${FILENAME}
else
echo "Значение не найдено, файл останется в ${DEPLOY_HOME}"
fi
done
}
#ГЛАВНАЯ ПРОГРАММА
getDeployedFiles
setDict
itArr
Текущая ошибка, которую я получаю:
“script.sh: строка x ‘a.script.100’: ошибка синтаксиса: ожидался операнд (ошибочный токен – “‘a.script.100’)
Похоже, что конструкция “if” не работает правильно, так как не выводит ни одного из последующих сообщений.
Не знаю, неправильно ли я управляю строками или что-то неверно в моей логике, любая помощь будет оценена. Кстати, я использую bash 4.4.
Ответ или решение
Проблема, о которой вы упомянули, связана с использованием ассоциативного массива в скрипте на Bash. Ваша ошибка возникает из-за неверного подхода к проверке наличия ключа в ассоциативном массиве. Давайте рассмотрим это подробнее и предложим решение.
Проблема
Ваш текущий код использует конструкции, которые могут вызывать ошибки при обработке ассоциативных массивов в Bash. В частности, проблема заключается в следующей строке:
if [[ -v "${dict['${i}']}" ]]; then
Использование кавычек и фигурных скобок на данном этапе неправильно. Правильная проверка наличия ключа в ассоциативном массиве требует немного другого подхода. Также важно убедиться, что скрипт правильно инициализирует ассоциативный массив.
Решение
Вот переписанный фрагмент вашего кода с корректной проверкой наличия ключа в ассоциативном массиве и улучшением логики программы:
#!/usr/bin/env bash
DEPLOY_HOME=/opt/xxx
function getDeployedFiles {
ls "${DEPLOY_HOME}" | grep -v pipeline.properties | grep -v Deploy.tmp > "${DEPLOY_HOME}/Deploy.tmp"
chmod 700 "${DEPLOY_HOME}/Deploy.tmp"
readarray -t depFilesArr < "${DEPLOY_HOME}/Deploy.tmp"
}
function setDict {
declare -A dict
dict=(
["a.script.100"]="/opt/xxx/firstpath/100"
["b.script.200"]="/opt/xxx/secondpath/200"
["c.script.300"]="/opt/xxx/thirdpath/300"
)
echo "${dict[@]}" # Вставьте эту строку для отладки, если необходимо
}
function itArr {
for i in "${depFilesArr[@]}"; do
FILENAME="${i}"
if [[ -n "${dict[${FILENAME}]}" ]]; then
echo "Значение присутствует для ${FILENAME}"
FILEDEST="${dict[${FILENAME}]}"
mv "${DEPLOY_HOME}/${FILENAME}" "${FILEDEST}/${FILENAME}"
else
echo "Значение не найдено, файл останется в ${DEPLOY_HOME}"
fi
done
}
# ОСНОВНАЯ ПРОГРАММА
getDeployedFiles
declare -A dict
setDict
itArr
Объяснение изменений
-
Корректная проверка ключа: Я изменил условную конструкцию с
[[ -v "${dict['${i}']}" ]]
на[[ -n "${dict[${FILENAME}]}" ]]
. В этом контексте-n
проверяет, не является ли строка пустой, а использование${FILENAME}
вместо‘${i}’
является правильным. Таким образом, код теперь корректно проверяет наличие значения. -
Инициализация ассоциативного массива: Я добавил объявление ассоциативного массива внутри главной программы. Убедитесь, что ваш массив
dict
доступен в функцииitArr
. -
Улучшение читаемости: Я добавил кавычки вокруг переменных и путей файлов, чтобы избежать проблем с пробелами или необычными символами в именах файлов и путях.
Эти изменения помогут избежать упомянутых вами ошибок и сделают код более устойчивым и понятным. Убедитесь, что у вас достаточно прав для выполнения перемещения файлов, и протестируйте код для различных сценариев.
Заключение
Правильное использование ассоциативных массивов в Bash требует внимательности к детали. Проверяя наличие ключей и правильное их формирование, вы можете избежать множества ошибок. Предложенные изменения не только исправят ваш случай, но и улучшат общую читаемость и поддержку вашего скрипта. Если у вас остались вопросы или требуется дополнительная помощь, не стесняйтесь обращаться!