【问题标题】:Issue with getopts and argument containing two '*'getopts 和包含两个“*”的参数的问题
【发布时间】:2016-11-27 14:16:13
【问题描述】:

我的脚本由 /bin/sh 解释并使用 getopts。当我这样做时:

$ ./check_files.sh -d /tmp -td -x*a*

-x 的 Ma 参数被很好地使用(最后):

+ find /tmp/geany_socket.9912fb56 /tmp/gpg-OBxSqk /tmp/log /tmp/ssh-bfbl8kSNDM8o /tmp/systemd-private-0a769fff0c124fed8a42ec56733ade46-systemd-timesyncd.service-09Wbx1 /tmp/. /tmp/.. /tmp/.ICE-unix /tmp/.Test-unix /tmp/.X0-lock /tmp/.X11-unix /tmp/.XIM-unix /tmp/.font-unix /tmp/.xfsm-ICE-BILXKY -prune -type d ! -name *a*

但如果我将 'a' 替换为 'i' :

$ ./check_files.sh -d /tmp -td -x*i*

我明白了:

+ find /tmp/geany_socket.9912fb56 /tmp/gpg-OBxSqk /tmp/log /tmp/ssh-bfbl8kSNDM8o /tmp/systemd-private-0a769fff0c124fed8a42ec56733ade46-systemd-timesyncd.service-09Wbx1 /tmp/. /tmp/.. /tmp/.ICE-unix /tmp/.Test-unix /tmp/.X0-lock /tmp/.X11-unix /tmp/.XIM-unix /tmp/.font-unix /tmp/.xfsm-ICE-BILXKY -prune -type d ! -name check_files.sh

由于独特的原因,我在当前目录中有一个名称中带有“i”的文件,此名称被传递给 find 命令(而不是实际参数 *i*。我用其他一些文件进行了测试…

我没有这个论点中只有一个“*”的问题。

我尝试使用单引号和双引号,但结果相同。

谁能解释一下为什么?

我使用调用破折号的shebang #!/usr/bin/env sh。我还用bash --posix 运行了脚本,我得到了不同的结果,但仍然是我上面描述的同样的问题。

根据@kenorb 的要求:

(x)
    SEARCH_NAME_EXCLUDE="${OPTARG}";
(i)
    SEARCH_NAME_INCLUDE="${OPTARG}";
;;

[…]

find_name_clause() {
    if [ -n "$1" ]
    then
    FIND_NAME_CLAUSE=" -name $1 "
    fi
    if [ "$1" -a "$2" ]
        then
            FIND_NAME_CLAUSE="${FIND_NAME_CLAUSE} -a "
        fi    
        if [ -n "$2" ]
        then
            FIND_NAME_CLAUSE="${FIND_NAME_CLAUSE} ! -name  $2 "
        fi    
}

find_name_clause "${SEARCH_NAME_INCLUDE}" "${SEARCH_NAME_EXCLUDE}"
FIND_CLAUSE="${FIND_TYPE_CLAUSE} ${FIND_NAME_CLAUSE}"

[…]


nb_files() {
    NB_FILES=$(find $1 $2 |wc -l)
}

nb_files "${search} ${FIND_CLAUSE}"

【问题讨论】:

  • 你能分享你的脚本的相关代码,尤其是find命令吗?也许你应该以-x'*a*' 运行脚本,因为在你的脚本运行之前,通配符已经展开了。

标签: shell getopts


【解决方案1】:

我设法做到了:

find_name_clause() {
        if [ $(expr length $1) -gt 2 ]
        then
            FIND_NAME_CLAUSE=" -name "$1
        fi
        if [ $(expr length $1) -gt 2 -a $(expr length $2) -gt 2  ]
        then
            FIND_NAME_CLAUSE=${FIND_NAME_CLAUSE}" -a "
        fi    
        if [ $(expr length $2) -gt 2  ]
        then
            FIND_NAME_CLAUSE=${FIND_NAME_CLAUSE}"! -name  "$2
        fi    
}

find_name_clause "'"${SEARCH_NAME_INCLUDE}"'" "'"${SEARCH_NAME_EXCLUDE}"'"

【讨论】:

    【解决方案2】:

    设置noglob

    set -o noglob
    

    之前

    ./check_files.sh -d /tmp -td -x*a*
    

    或者这样称呼

    ./check_files.sh -d /tmp -td -x\*i\* # -x'*i*' will do the same
    

    【讨论】:

    • 还是一样。也许我必须在脚本的其他地方使用这种结构。
    • @Stéphane Sjsam 的建议解决了如何调用脚本的问题。然而,脚本本身也需要修改。请参阅:"I'm trying to put a command in a variable, but the complex cases always fail!"
    • @Stéphane 如果您阅读我留下的链接,您会发现最好放弃您正在做的事情并重新开始使用数组。
    • @Stéphane:我支持 \@john1024 的建议。
    • @John1024 :它实际上并没有解决我的问题……但无论如何谢谢你,我已经知道要搜索什么了。
    猜你喜欢
    • 2021-03-28
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多