bash:传递几个包含文件名的空格

Kre*_*uvf 1 bash path whitespace escape-characters

在 bash 脚本中,我将 PDF 逐页光栅化为单个文件,最后生成的单个 PNG 再次合并到 PDF 中,如下所示:

\n\n
convert -monitor /path/to/1.png /path/to/2.png /path/to/3.png ... output.pdf\n
Run Code Online (Sandbox Code Playgroud)\n\n

脚本仍然存在的唯一问题是无法正确处理带有空格的文件。以下是我尝试过的一些事情:

\n\n
newfile=$(sed -r -e \'s| |\\\\ |g\' <<< "$tmppath$curr.png")\necho "DEBUG: newfiles : $newfiles"\nfilearray[$curr-1]="$newfiles"\necho "DEBUG: filearray: ${filearray[*]}"\n
Run Code Online (Sandbox Code Playgroud)\n\n

这产生(每页/文件):

\n\n
DEBUG: newfiles : /tmp/pngpdf/file\\ with\\ spaces/1.png\nDEBUG: filearray: /tmp/pngpdf/file\\ with\\ spaces/1.png\n
Run Code Online (Sandbox Code Playgroud)\n\n

后来,我有两条调试消息

\n\n
echo "DEBUG: filearray: ${filearray[*]}"\necho "DEBUG:            ${filearray[0]}, ${filearray[1]}, ${filearray[2]}, ..."\n
Run Code Online (Sandbox Code Playgroud)\n\n

查看filearray多个文件/页面的外观:

\n\n
DEBUG: filearray: /tmp/pngpdf/file\\ with\\ spaces/1.png /tmp/pngpdf/file\\ with\\ spaces/2.png /tmp/pngpdf/file\\ with\\ spaces/3.png /tmp/pngpdf/file\\ with\\ spaces/4.png /tmp/pngpdf/file\\ with\\ spaces/5.png\nDEBUG:            /tmp/pngpdf/file\\ with\\ spaces/1.png, /tmp/pngpdf/file\\ with\\ spaces/2.png, /tmp/pngpdf/file\\ with\\ spaces/3.png, ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

我可以清楚地看到以下内容:

\n\n
    \n
  1. 对于每个文件,只有一个数组元素。
  2. \n
  3. 每个空格前面都有一个\\.
  4. \n
\n\n

我首先将整个命令放入一个变量中,看看会执行什么:

\n\n
execcmd="convert -monitor ${filearray[@]} output.pdf"\n
Run Code Online (Sandbox Code Playgroud)\n\n

一个例子可能看起来像这样:

\n\n
convert -monitor /tmp/pngpdf/file\\ with\\ spaces/1.png /tmp/pngpdf/file\\ with\\ spaces/2.png /tmp/pngpdf/file\\ with\\ spaces/3.png /tmp/pngpdf/file\\ with\\ spaces/4.png /tmp/pngpdf/file\\ with\\ spaces/5.png output.pdf\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是使用$execcmdConvert 执行它会向我抛出许多错误:

\n\n
convert.im6: unable to open image `/tmp/pngpdf/file\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `/tmp/pngpdf/file\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `with\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `with\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `spaces/1.png\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: unable to open file `spaces/1.png\' @ error/png.c/ReadPNGImage/3667.\nconvert.im6: unable to open image `/tmp/pngpdf/file\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `/tmp/pngpdf/file\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `with\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `with\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `spaces/2.png\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: unable to open file `spaces/2.png\' @ error/png.c/ReadPNGImage/3667.\nconvert.im6: unable to open image `/tmp/pngpdf/file\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `/tmp/pngpdf/file\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `with\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `with\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `spaces/3.png\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: unable to open file `spaces/3.png\' @ error/png.c/ReadPNGImage/3667.\nconvert.im6: unable to open image `/tmp/pngpdf/file\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `/tmp/pngpdf/file\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `with\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `with\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `spaces/4.png\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: unable to open file `spaces/4.png\' @ error/png.c/ReadPNGImage/3667.\nconvert.im6: unable to open image `/tmp/pngpdf/file\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `/tmp/pngpdf/file\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `with\\\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: no decode delegate for this image format `with\\\' @ error/constitute.c/ReadImage/544.\nconvert.im6: unable to open image `spaces/5.png\': No such file or directory @ error/blob.c/OpenBlob/2638.\nconvert.im6: unable to open file `spaces/5.png\' @ error/png.c/ReadPNGImage/3667.\nconvert.im6: no images defined `output.pdf\' @ error/convert.c/ConvertImageCommand/3044.\n
Run Code Online (Sandbox Code Playgroud)\n\n

显然,它无法正确识别我想要做什么。反斜杠本身被转义,因此,空格重新获得了它们的参数界定能力。当直接将该命令放入 bash 时,它运行顺利(如预期):

\n\n
$ convert -monitor /tmp/pngpdf/file\\ with\\ spaces/1.png /tmp/pngpdf/file\\ with\\ spaces/2.png /tmp/pngpdf/file\\ with\\ spaces/3.png /tmp/pngpdf/file\\ with\\ spaces/4.png /tmp/pngpdf/file\\ with\\ spaces/5.png output.pdf\nLoad/Image//tmp/pngpdf/file with spaces[1.png]: 584 of 585, 100% complete\nLoad/Image//tmp/pngpdf/file with spaces[2.png]: 584 of 585, 100% complete\nLoad/Image//tmp/pngpdf/file with spaces[3.png]: 584 of 585, 100% complete\nLoad/Image//tmp/pngpdf/file with spaces[4.png]: 584 of 585, 100% complete\nLoad/Image//tmp/pngpdf/file with spaces[5.png]: 584 of 585, 100% complete\nMogrify/Image//tmp/pngpdf/file with spaces[5.png]: 4 of 5, 100% complete\nresize image[output.pdf]: 180 of 181, 100% complete\nresize image[output.pdf]: 180 of 181, 100% complete\nresize image[output.pdf]: 180 of 181, 100% complete\nresize image[output.pdf]: 180 of 181, 100% complete\n
Run Code Online (Sandbox Code Playgroud)\n\n

这让我非常困惑,我不知道如何解决这个问题。我也尝试保存 filearray 中引用的单个文件名,但没有DEBUG: filearray: "/tmp/pngpdf/file with spaces/1.png" "/tmp/pngpdf/file with spaces/2.png" "/tmp/pngpdf/file with spaces/3.png" "/tmp/pngpdf/file with spaces/4.png" "/tmp/pngpdf/file with spaces/5.png"效果。bash 可能也会转义这些特殊字符。我确信这一定与 bash 的工作原理有关,但似乎我的理解还不足以自行解决这个问题。因此,如果有人能够启发我,我会非常高兴。:)

\n\n

PS:我一直在几个地方寻找我的问题的答案(Shell script issues with filenames contains spaceUsing a generated list of filenames as argument list \xe2\x80\x94 with space循环遍历带有空格的文件名称?Bash 脚本和其中包含空格的文件为什么我的 shell 脚本会因空格或其他特殊字符而阻塞?文件名中包含空格的脚本出现问题)。不幸的是,我无法在那里找到我的问题的答案。也许已经太晚了;)

\n

roa*_*ima 5

execcmd="convert -monitor ${filearray[@]} 输出.pdf"

但是用$execcmdConvert 执行它会给我带来很多错误

不要调用$execcmd,因为它已经失去了文件名和文件名的空格分隔部分之间的区别。相反,使用带引号的参数执行命令本身:

    convert -monitor "${filearray[@]}" output.pdf
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

618 次

最近记录:

10 年,5 月 前