Страницы

Поиск по вопросам

пятница, 5 апреля 2019 г.

Почему плохо перебирать файлы/папки через ls? (Iterating over ls output is fragile. Use globs.)

Есть код, который должен работать в 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}'

Комментариев нет:

Отправить комментарий