Использование оператора if для проверки наличия файлов в папке с использованием подстановочного знака

Думаю, -@поддерживается только в Solaris (и системах на базе Solaris, таких как Illumos ). В Solaris расширенные атрибуты можно рассматривать как файлы в ортогональном пространстве имен; теоретически любой файл (в общем смысле, включая каталоги и т. д. )может иметь расширенные атрибуты, которые сами могут иметь расширенные атрибуты и т. д. Для изучения этого леса атрибутов существуют API, которые позволяют им обрабатываться как дерево файлов, и это то, что cd -@использует (и -@для других команд ). Подробнее см. fsattr(5). Это может быть ограничено в зависимости от поддерживаемой файловой системы; например, UFS не позволяет использовать каталоги в качестве атрибутов и не позволяет атрибутам самим иметь атрибуты.

В Solaris это выглядит так, как вы предлагаете:

~$ touch test
~$ cd -@ test
/proc/1604/fd/6$ ls
SUNWattr_ro  SUNWattr_rw
/proc/1604/fd/6$ touch attribute

При этом создается файл расширенных атрибутов «атрибут», прикрепленный к файлу «тест». cd -@ attributeтоже работает внутри дерева атрибутов, и можно продолжить поиск в кроличьей норе.

Аналогичный API расширенных атрибутов был запущен недавно (в январе 2019 года )для Linux, в частности, в рамках обсужденияfs-verity.

1
10.01.2019, 23:14
3 ответа

Спасибо всем. Я смог получить то, что мне было нужно от:

if ls -lrt ESGSN_*.SMS.EDR ; then
0
28.01.2020, 00:21

Есть два способа ответить на этот :исправление вашего текущего скрипта или предложить альтернативу, которая будет быстрее и точнее. Я попробую оба:)

Во-первых, проблема с вашим скриптом в том виде, в каком он есть, заключается в том, что [ "ESGN_*.SMS.EDR" ]всегда будет оцениваться как истина. Конструкция [ "<string>" ]просто проверяет, не является ли строка -пустой. Даже когда файлов нет, указанная вами строка не -пуста, поэтому тест ничего не делает.

Что вам нужно сделать, чтобы исправить это, так это перебрать все файлы и проверить, соответствуют ли они шаблону. Следующие работы для меня:

for F in *; do
    if [[ "$F" =~ ESGSN_.*\.SMS\.EDR ]]; then
        printf "Processing '%s'\n" "$F"
        gzip < "$F" > "$F.gz"
    fi
done

Однако на самом деле я бы поступил иначе, если бы захотел решить эту проблему для собственного использования. Вместо этого быстрее и естественнее использовать GNU find, который легко выполняет сопоставление с образцом -:

.
find./ -type f -regex ".*/ESGSN_.*\.SMS\.EDR" -exec bash -c "gzip < {} > {}.gz" \;

Команда findочень мощная, и если вы собираетесь часто использовать Linux, вам следует с ней ознакомиться. Рекомендую просмотреть man find.

0
28.01.2020, 00:21
if ! gzip ESGSN_*.SMS.EDR 2>/dev/null; then
    printf 'No files to process (gzip exit code: %d)\n' "$?"
fi

Ваш тест всегда будет верным, так как строка ESGSN_*.SMS.EDRне -пуста. Подстановка *не будет обрабатываться, если она заключена в двойные кавычки.

Кроме того, большинство оболочек по умолчанию сохраняют шаблон нераскрытым, если он ничему не соответствует, что в вашем случае означает, что ваш код в конечном итоге создаст пустой файл с именем ESGSN_*.SMS.EDR.gz, если шаблон не соответствует ни одному имени файла..

Приведенный выше код просто попытается сжать все файлы, соответствующие шаблону, и в случае неудачи выведет сообщение.

0
28.01.2020, 00:21

Теги

Похожие вопросы