Есть код, который должен работать в 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.
В чём "хрупкость" этого метода? Как я могу его улучшить?
Очевидный вариант "использовать глобы" не подходит, т.к. нужна сортировка по времени.
Ответ
Проблема в том, что ls предназначена в первую очередь для отображения списка файлов в понятном пользователю формате. Это включает всякие метки и прочие обозначения, которые ls прибавляет к наименованиям файлов.
ls -1 не добавляет меток, но это не избавляет от «расцвечивания». Кроме того, работа ls может варьироваться от настроек окружения и операционной системы, что переводит её из разряда «универсальное решение» в разряд «может работать».
Так же не стоит забывать, что совсем нередко пользователи при помощи алиаса задают дефолтные настройки для ls
Для того, чтобы получить некий список файлов и передать его в качестве параметров какой-то другой команде, обычно используют find. Например, чтобы получить список поддиректорию в текущей директории, отсортированный по mtime, можно сделать как-нибудь так:
find . -maxdepth 1 -type d -printf “%C@ %p
" | sort | awk '{print $2}'
Комментариев нет:
Отправить комментарий