Думаю, -@
поддерживается только в 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
.
Спасибо всем. Я смог получить то, что мне было нужно от:
if ls -lrt ESGSN_*.SMS.EDR ; then
Есть два способа ответить на этот :исправление вашего текущего скрипта или предложить альтернативу, которая будет быстрее и точнее. Я попробую оба:)
Во-первых, проблема с вашим скриптом в том виде, в каком он есть, заключается в том, что [ "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
.
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
, если шаблон не соответствует ни одному имени файла..
Приведенный выше код просто попытается сжать все файлы, соответствующие шаблону, и в случае неудачи выведет сообщение.