Shell 脚本:每行调用两次?

Shell 脚本:每行调用两次?

我有一个用于将图像转换为刺绣效果的 shell 脚本。这是脚本:刺绣脚本

此脚本是 Web 应用程序的一部分。它在我的 Mac 上正常运行,但是,在我部署到运行 CentOS 7 的 Web 服务器上后,我注意到当我调用它(显示手册页)时,每一行都是重复的,请参阅:

刺绣.sh:

用法:刺绣 [-n 数量颜色] [-p 图案] [-t 厚度] [-g 灰度限制]
用法:刺绣 [-n 数量颜色] [-p 图案] [-t 厚度] [-g 灰度限制]
[-f 模糊度] [-b 背景颜色] [-a 角度] [-r 范围] [-i 强度] [-e 程度]
[-f 模糊度] [-b 背景颜色] [-a 角度] [-r 范围] [-i 强度] [-e 程度]

这只是前几行,但它对帮助的每一行都这样做。此外,脚本不再起作用,因为当我上传图像通过我的应用程序进行转换时,脚本会从甚至不到 1 Mb 的原始文件生成巨大的文件(137 Mb)。

我真的很困惑这里发生了什么。你知道是什么原因造成的吗?

这可能与操作系统有关吗?即使我使用这样的路径运行脚本,脚本是否可能位于其他地方并同时被调用两个版本lib/embroidery/embroidery.sh

更新 :所以这个问题与这种行为无关,John 对此进行了很好的解释,但脚本生成大文件的问题是由 CentOS repo 中提供的旧版本 ImageMagick 引起的,我更新到 7.0.3 后它又可以正常工作了

答案1

在您的脚本中,我观察到帮助消息是通过以下方式生成的:

usage2()
    {
    echo >&2 ""
    echo >&2 "$PROGNAME:" "$@"
    sed >&2 -e '1,/^####/d;  /^######/g;  /^#/!q;  s/^#*//;  s/^ //;  4,$p' "$PROGDIR/$PROGNAME"
    }

让我们仔细看看 sed 命令:

sed >&2 -e '1,/^####/d;  /^######/g;  /^#/!q;  s/^#*//;  s/^ //;  4,$p' embroidery

问题是 (1) 默认情况下,sed打印命令末尾模式空间中剩余的内容,但 (2) 该命令4,$p会导致额外的打印。因此,每一行都会打印两次。

一种解决方案是使用-n选项来抑制默认打印:

sed >&2 -ne '1,/^####/d;  /^######/g;  /^#/!q;  s/^#*//;  s/^ //;  4,$p' embroidery

由于OSX(BSD)和CentOS(Linux)使用不同版本的sed,因此确实会出现一些兼容性问题。


顺便说一句,这个稍微简单一点的 sed 命令对我来说很有用:

sed >&2 -ne '/^#####/q; 1,/^####/d; s/^#* *//p' embroidery

迷你示例

仅提取一些关键行,您的脚本看起来类似于:

$ cat testfile
#!/bin/bash
#
# misc info 1
# misc info 2
#
####
#
# USAGE: embroidery [-n numcolors ] [-p pattern] [-t thickness] [-g graylimit]
# [-f fuzzval] [-b bgcolor] [-a angle] [-r range] [-i intensity] [-e extent]
# [-N newseed] [-M mix] infile outfile
######
#
usage2()
        {
        sed >&2 -e '1,/^####/d;  /^######/g;  /^#/!q;  s/^#*//;  s/^ //;  4,$p' "$0"
        }

if [ $# -eq 0 ]
then
        # help information
        usage2
        exit 0
fi

如果我们运行此脚本,输出如下所示:

$ ./testfile 


USAGE: embroidery [-n numcolors ] [-p pattern] [-t thickness] [-g graylimit]
USAGE: embroidery [-n numcolors ] [-p pattern] [-t thickness] [-g graylimit]
[-f fuzzval] [-b bgcolor] [-a angle] [-r range] [-i intensity] [-e extent]
[-f fuzzval] [-b bgcolor] [-a angle] [-r range] [-i intensity] [-e extent]
[-N newseed] [-M mix] infile outfile
[-N newseed] [-M mix] infile outfile

我们将上面的 sed 命令替换为:

    sed >&2 -ne '/^#####/q; 1,/^####/d; s/^#* *//p' "$0"

现在,输出如下所示:

$ ./testfile2

USAGE: embroidery [-n numcolors ] [-p pattern] [-t thickness] [-g graylimit]
[-f fuzzval] [-b bgcolor] [-a angle] [-r range] [-i intensity] [-e extent]
[-N newseed] [-M mix] infile outfile

相关内容