Вопрос или проблема
Я пишу скрипт для перемещения данных, и хочу иметь возможность создавать родительский каталог, в который я отправляю свои данные, чтобы переименовывать/очищать имена файлов. Мне нужно отслеживать вновь созданные каталоги, чтобы изменить права доступа на указанный входной аргумент. Поскольку mkdir -vp
может выводить созданные каталоги, это казалось идеальным, однако я не могу разыменовать кавычки, чтобы использовать вывод, и eval
кажется единственным вариантом. Я понимаю, что, вероятно, мог бы просто циклом проверять существование каждого каталога, но это кажется расточительным, когда mkdir
уже выводит его.
Это мой код на данный момент:
readarray -t ndir < <(ssh myhost mkdir -vp foo/ | grep -oP "^mkdir: created directory\s+\K['\"].+['\"](?=$)" | sort -r)
eval ndir=("${ndir[@]}")
ssh myhost chmod 555 "${ndir[@]}"
Как я понимаю, eval
считается довольно опасным, но я не вижу никакого жизнеспособного и удобного решения, кроме как вручную перебрать и проверить, какие части пути существуют. Есть ли более безопасный и альтернативный способ?
Ответ или решение
Для решения вашей задачи, касающейся создания директорий с помощью команды mkdir -p
и последующей обработки их вывода, действительно стоит рассмотреть более безопасные и эффективные методы, чем использование команды eval
. Подход, который вы применяете сейчас, демонстрирует понимание программирования в Unix-системах, но использование eval
может привести к потенциально серьезным рискам безопасности и сложным ошибкам.
1. Понимание контекста проблемы
Вы хотите создать необходимые директории на удаленной машине, используя SSH, и затем изменить права доступа к ним. При этом требуется сохранить информацию об успешно созданных директориях для дальнейшего использования. Текущий метод с использованием eval
может привести к проблемам, если будут некорректно обработаны специальные символы и пробелы в именах директорий.
2. Альтернативный подход
Вместо использования eval
, вы можете выполнить обработку вывода команд непосредственно через массивы и функции bash. Рассмотрим алгоритм, который будет более безопасным и эффективным.
Измененный код
# Создаем массив для хранения директории
readarray -t ndir < <(ssh myhost 'mkdir -vp foo/ | grep -oP "^mkdir: создана директория\s+\K[^\s]+"')
# Проверяем, были ли созданы директории и обрабатываем только их
if [[ ${#ndir[@]} -gt 0 ]]; then
ssh myhost chmod 555 "${ndir[@]}"
else
echo "Директории не были созданы."
fi
3. Объяснение кода
readarray -t ndir < <(ssh myhost '...')
: Этот код использует подстановку процесса для получения вывода командыmkdir -vp
. Мы используем одинарные кавычки для передачи аргументов и предотвратить нежелательные подстановки.grep -oP
: Шаблон regex будет искать строки, начинающиеся наmkdir: создана директория
, и получать только названия директорий.if [[ ${#ndir[@]} -gt 0 ]]
: Мы проверяем, содержится ли в массивеndir
элементы. Если да, то продолжаем выполнять командуchmod
.
4. Преимущества предложенного подхода
- Безопасность: Отказ от использования
eval
делает ваш скрипт менее уязвимым к атакам через инъекции команд. - Читаемость и поддержка: Код становится более понятным и простым для анализа, что значительно облегчает его сопровождение.
- Оптимизация производительности: Упрощается логика, что позволяет избежать лишних циклов и проверок.
Заключение
Применяя предложенный метод, вы сможете обеспечить создание директорий и изменение их прав доступа без использования eval
, что значительно улучшает безопасность и надежность вашего скрипта. Такие изменения могут способствовать более эффективной работе с удаленными файлами и директориями, обеспечивая при этом предсказуемый и безопасный опыт работы с shell-скриптами. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать их!