Bash 脚本虽然按预期工作,但还是给出警告/错误。我该如何编辑以删除警告/错误?

Bash 脚本虽然按预期工作,但还是给出警告/错误。我该如何编辑以删除警告/错误?

我使用以下脚本将位于子目录中的图像序列批量合并到 .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.  

对于每个包含图像的目录,依此类推。

答案1

问题是,如果您遇到没有匹配图像文件的目录,则 glob 会以未扩展的形式传递给 convert 命令,因此您最终会尝试转换具有文字名称的文件./*jpg./*png依此类推。

对此的通常解决方案(在 bash 和其他支持它的 shell 中)是启用空值通配符。不幸的是,在这种情况下,这只会产生不同的错误,因为现在您在调用时convert根本没有任何输入文件。

除了设置、扩展数组中的 glob,然后明确测试数组是否为空之外,我想不出更优雅的方法来处理这个问题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

答案2

错误是由于缺少匹配的文件而导致的。但不要解析输出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

相关内容