Intereting Posts
X Пересылка с косвенным рендерингом завершается неудачей с более новыми клиентами Debian Jessie не может установить расширение GNOME, не обнаружен собственный соединитель узла Как временно отключить клавишу Escape в терминале? Что такое эквивалент KDE сценария Nautilus? Двоичный файл поврежден после упаковки Как перезагрузить все запущенные приложения из места подкачки в оперативную память? Является ли ctime на linux всегда больше или равно mtime? Можете ли вы кодировать url (percent) с помощью инструмента перекодировки Получение количества файлов во время итерации через каталоги и папки Печать диапазонов вывода с эхом Как сохранить VPN-соединение в режиме ожидания или ограничить время ожидания? bash: раскрасить второй столбец вывода Проблема Tmux Terminfo с привязкой клавиш Zsh Утилита для получения двоичного представления из строки? Как совместить классы символов POSIX регулярного выражения?

bash: обработка ошибок на find -exec

Я использовал этот маленький скрипт для поиска искаженных образов:

find -name '*.jpg' -exec identify -format "%f\n" {} \; 2>errors.txt 

Он работал достаточно хорошо, но теперь мне нужно немного изменить его. Вместо того, чтобы сбрасывать stderr на errors.txt, я хочу сбросить имя файла (% f) изображения, вызвавшего ошибку. То есть, я хочу список искаженных файлов изображений в файле errors.txt вместо сообщений об ошибках списка.

Я попробовал добавить || echo «% f» >> errors.txt к части -exec, но это не сработало. Какой был бы лучший способ сделать это?

Это находит искаженные изображения и сохраняет их имена в names.txt :

 find -name '*.jpg' -exec bash -c 'identify "$1" &>/dev/null || echo "$1">>names.txt' none {} \; 

Как это работает

  • find -name '*.jpg'

    Это начинается как обычно.

  • -exec bash -c 'identify "$1" &>/dev/null || echo "$1" >>names.txt' none {} \;

    Этот пробег identify в каждом файле и, если identify возвращает ненулевой код ошибки, он переименовывает имя файла в names.txt .

    bash -c '...' none {} заставляет команду bash запускать команду в кавычках с именем файла в {} назначенной на позиционный аргумент $1 .

    Для любопытных строка none присваивается $0 . $0 не используется, если bash не генерирует ошибку, и в этом случае она появится в сообщении об ошибке как имя программы .

обсуждение

Я попробовал добавить || echo "%f" >> errors.txt || echo "%f" >> errors.txt к части -exec, но это не сработало. Какой был бы лучший способ сделать это?

Тонкость заключается в том, что || должен работать с командой identify . Для этого нам нужно поместить identify в оболочку, например, используя bash -c как показано выше.

 find . -name '*.jpg' -exec sh -c ' for file do if identify "$file"; then printf "%s\n" "$file" >&3 else printf "%s\n" "$file" >&4 fi done' sh {} + 3> good 4> bad > /dev/null 2>&1 

Итак, вы хотите, как …

 find . -name '*.jpg' \ ! -exec identify -silent {} \; \ -print 2>/dev/null >errors.txt