#bash #shell #инспекция_кода #zsh
Есть код, который должен работать в bash и zsh. Фрагмент кода перечисляет все директории, сортируя их по времени последнего изменения. Эту задачу он решает вполне успешно. Перечисляемые директории генерятся тем же кодом и содержат только символы a-zA-Z0-9-_, никаких пробелов. mcve.sh: #!/usr/bin/env bash for i in $(ls -dt1 ./*/); do echo "${i}"; done Использую shellcheck: shellcheck mcve.sh Получаю следующий результат: In mcve.sh line 2: for i in $(ls -dt1 ./*/); ^-- SC2045: Iterating over ls output is fragile. Use globs. В чём "хрупкость" этого метода? Как я могу его улучшить? Очевидный вариант "использовать глобы" не подходит, т.к. нужна сортировка по времени.
Ответы
Ответ 1
Проблема в том, что ls предназначена в первую очередь для отображения списка файлов в понятном пользователю формате. Это включает всякие метки и прочие обозначения, которые ls прибавляет к наименованиям файлов. ls -1 не добавляет меток, но это не избавляет от «расцвечивания». Кроме того, работа ls может варьироваться от настроек окружения и операционной системы, что переводит её из разряда «универсальное решение» в разряд «может работать». Так же не стоит забывать, что совсем нередко пользователи при помощи алиаса задают дефолтные настройки для ls. Для того, чтобы получить некий список файлов и передать его в качестве параметров какой-то другой команде, обычно используют find. Например, чтобы получить список поддиректорию в текущей директории, отсортированный по mtime, можно сделать как-нибудь так: find . -maxdepth 1 -type d -printf “%C@ %p\n" | sort | awk '{print $2}'Ответ 2
под «хрупкостью», вероятно, подразумевалась обработка спец-символов, которые могут встретиться в именах файлов/каталогов. например, пробел: $ mkdir "1 2" 3 $ for i in $(ls); do echo "${i}"; done 1 2 3 в то время как использование glob даст корректный результат: $ for i in *; do echo "${i}"; done 1 2 3 данной проблемы можно избежать, если заключить вложенную команду в кавычки: $ for i in "$(ls)"; do echo "${i}"; done 1 2 3
Комментариев нет:
Отправить комментарий