![为什么我的 shell 脚本不按顺序执行? (可能是 imagemagick?)](https://linux22.com/image/123698/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%9A%84%20shell%20%E8%84%9A%E6%9C%AC%E4%B8%8D%E6%8C%89%E9%A1%BA%E5%BA%8F%E6%89%A7%E8%A1%8C%EF%BC%9F%20%EF%BC%88%E5%8F%AF%E8%83%BD%E6%98%AF%20imagemagick%EF%BC%9F%EF%BC%89.png)
我制作了一个简单的 bash shell 脚本,对目录中的每个文件执行三个 imagemagick 命令。我没有使用 & 也没有 |使每个命令同时运行。
#!/bin/bash
jpg="$1/*.jpg"
jpeg="$1/*.jpeg"
JPG="$1/*.JPG"
png="$1/*.png"
#convert to png
to_png() {
for file in $jpg; do mogrify -format png $file; rm $file; done
for file in $jpeg; do mogrify -format png $file; rm $file; done
for file in $JPG; do mogrify -format png $file; rm $file; done
}
#format for 4k
to_4k() {
for file in $png; do convert $file -resize 3840x2160 $file; done
}
#put on transparent background
to_trans() {
for file in $png; do composite -gravity center $file -geometry 3840x2160 /path/to/transparent/background $file; done
}
do_stuff() {
to_png
to_4k
to_trans
}
if [ -d "$1" ];
then do_stuff
else echo "You didn't enter a directory. Please try again."
fi
当目录中有任何 .jpg 文件时,我会收到错误消息。 ImageMagick 是否在文件完成之前告诉 bash 命令已完成?
convert: Expected 8 bytes; found 0 bytes `/path/to/picture/image.png' @ warning/png.c/MagickPNGWarningHandler/1669.
convert: Read Exception `/path/to/picture/image.png' @ error/png.c/MagickPNGErrorHandler/1643.
convert: corrupt image `/path/to/picture/image.png' @ error/png.c/ReadPNGImage/3973.
convert: no images defined `/path/to/picture/image.png' @ error/convert.c/ConvertImageCommand/3210.
composite: Expected 8 bytes; found 0 bytes `/path/to/picture/image.png' @ warning/png.c/MagickPNGWarningHandler/1669.
在命令之间使用长时间睡眠可以解决此问题,但它非常草率。
旁注:我将目录存储在变量中,因为在 for 循环中使用 $1/*.jpg 显然无法扩展 $1 和 * 。 Bash 返回错误,指出 /path/to/*.jpg 不存在。
我使用的是 Ubuntu 16.04 (x86_64)、GNU bash 4.3.48 和 ImageMagick 6.8.9-9
答案1
$1
内部函数与外部函数不同$1
。
所以你需要将其保存在 script begin: dir="$1"
,...并$dir
在其他地方使用。
这样你将解决你自己注意到的第一个奇怪的事情(bash:路径不存在)......但它可能会解决其他所有问题。
您的解决方法不完整,您必须将变量放在引号中,但是全球扩展将是错误的......您唯一能做的就是清理代码,因为脚本的简化版本肯定可以很好地工作:
#!/bin/bash
shopt -s nullglob ; set -o xtrace #xtrace for debug
dir="$1" ; [ -d "$dir" ] || dir=.
for file in "$dir"/*.{jpg,jpeg,JPG}; do mogrify -format png "$file"; rm "$file"; done
for file in "$dir"/*.png; do convert "$file" -resize 3840x2160 "$file"; done
for file in "$dir"/*.png; do composite -gravity center "$file" -geometry 3840x2160 /home/d/bin/youtube_tools/4kclear.png "$file"; done