Ассоциативный массив содержит имена файлов и пути.

Вопрос или проблема

У меня есть конвейер, который развертывает скрипты во временную директорию. Мне нужно переместить их в их фактическую правильную директорию.

#!/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 

Объяснение изменений

  1. Корректная проверка ключа: Я изменил условную конструкцию с [[ -v "${dict['${i}']}" ]] на [[ -n "${dict[${FILENAME}]}" ]]. В этом контексте -n проверяет, не является ли строка пустой, а использование ${FILENAME} вместо ‘${i}’ является правильным. Таким образом, код теперь корректно проверяет наличие значения.

  2. Инициализация ассоциативного массива: Я добавил объявление ассоциативного массива внутри главной программы. Убедитесь, что ваш массив dict доступен в функции itArr.

  3. Улучшение читаемости: Я добавил кавычки вокруг переменных и путей файлов, чтобы избежать проблем с пробелами или необычными символами в именах файлов и путях.

Эти изменения помогут избежать упомянутых вами ошибок и сделают код более устойчивым и понятным. Убедитесь, что у вас достаточно прав для выполнения перемещения файлов, и протестируйте код для различных сценариев.

Заключение

Правильное использование ассоциативных массивов в Bash требует внимательности к детали. Проверяя наличие ключей и правильное их формирование, вы можете избежать множества ошибок. Предложенные изменения не только исправят ваш случай, но и улучшат общую читаемость и поддержку вашего скрипта. Если у вас остались вопросы или требуется дополнительная помощь, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...