Я использую следующий сценарий для последовательностей изображений пакетного объединения, расположенных в подкаталогах в файлы pdf. Это работает хорошо, но печатает ошибки при работе. Я интересуюсь совершенствованием сценария для удаления ошибок.
#!/bin/bash
for i in $(find . -type d)
do
convert "${i}/*jpg" "${i}/*png" "${i}/*tif" "${i}/*tiff" "${i}.pdf"
done
Пример ошибок ниже..
convert: unable to open image `./*jpg': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `./*png': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `./*tif': No such file or directory @ error/blob.c/OpenBlob/2712.
И т. д. и т. п. для каждого каталога, содержащего формирование изображений.
Проблема - то, что при обнаружении с каталогом без соответствия файлам изображений шарик передается нерасширенный до команды преобразования, таким образом, Вы заканчиваете тем, что пытались преобразовать файлы с литеральным именем ./*jpg
, ./*png
и так далее.
обычное решение для этого (в ударе и других оболочках, которые поддерживают его) состоит в том, чтобы включить пустой globbing. К сожалению, в этом случае это просто создает другую ошибку, так как теперь Вы звоните convert
без любых входных файлов вообще.
я не могу думать о более изящном способе обработать это кроме установки nullglob
, разворачивая шарики в массиве, и затем явно тестируя, пуст ли массив или нет. Так, например:
find $PWD -type d -execdir bash -c '
shopt -s nullglob
files=("$1"/*.jpg "$1"/*.png)
if (( ${#files[@]} == 0 )); then
echo "$1: nothing to do here"
else
convert "${files[@]}" "$1.pdf"
fi' bash {} \;
или более сжато
find $PWD -type d -execdir bash -c '
shopt -s nullglob
files=("$1"/*.jpg "$1"/*.png)
(( ${#files[@]} == 0 )) || convert "${files[@]}" "$1.pdf"
' bash {} \;
или, беря на себя инициативу @Zanna и покончив find
в целом:
#!/bin/bash
shopt -s globstar
shopt -s nullglob
for f in **/*; do
[[ -d "$f" ]] || continue
files=( "$f"/*.jpg "$f"/*.png )
(( ${#files[@]} != 0 )) || continue
convert "${files[@]}" "$f.pdf"
done
Ошибки вызываются отсутствием соответствия файлам там. Но не анализируйте вывод find
- используют globstar и тест вместо этого.
shopt -s globstar
for i in **; do
[[ -d "$i" ]] &&
convert "$i"/*jpg "$i"/*png "$i"/*tif "$i"/*tiff "$i".pdf 2>/dev/null
done
shopt -u globstar