加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash:部分匹配一个完整的单词

发布时间:2020-12-15 21:06:16 所属栏目:安全 来源:网络整理
导读:我写了一个bash脚本,它将一个命令作为第一个位置参数,并使用case构造作为类似于以下内容的调度: do_command() { # responds to invocation `$0 command ...`}do_copy() { # respond to invocation: `$0 copy...`}do_imperative() { # respond to invocation
我写了一个bash脚本,它将一个命令作为第一个位置参数,并使用case构造作为类似于以下内容的调度:

do_command() {
  # responds to invocation `$0 command ...`
}

do_copy() {
  # respond to invocation: `$0 copy...`
}

do_imperative() {
  # respond to invocation: `$0 imperative ...`
}

cmd=$1
shift
case $cmd in
command)
  do_command $*
  ;;
copy)
  do_copy $*
  ;;
imperative)
  do_imperative $*
  ;;
*)
  echo "Usage: $0 [ command | copy | imperative ]" >&2
  ;;
esac

此脚本根据$1决定调用哪个函数,然后将剩余的参数传递给该函数.我想在不同的部分匹配上添加能力调度,但我希望以优雅的方式进行(优雅定义为既易于阅读又不会像眼睛或分心那样冗长的方式).

明显的功能(但不是优雅)解决方案可能是这样的:

case $cmd in
command|comman|comma|comm|com)
  do_command $*
  ;;
copy|cop)
  do_copy $*
  ;;
imperative|imperativ|imperati|imperat|impera|imper|impe|imp|im|i)
  do_imperative $*
  ;;
*)
  echo "Usage: $0 [ command | copy | imperative ]" >&2
  ;;
esac

正如您所看到的,显式枚举每个命令名称的所有不同排列都会变得非常混乱.

有一会儿,我觉得使用像这样的通配符可能没问题:

case $cmd in
com*)
  do_command $*
  ;;
cop*)
  do_copy $*
  ;;
i*)
  do_imperative $*
  ;;
*)
  echo "Usage: $0 [ command | copy | imperative ]" >&2
  ;;
esac

这不是一个眼睛.但是,这可能会导致不良行为,例如当$1作为“comblah”或其他不应被识别为有效参数的其他内容时调用do_command.

我的问题是:正确调度这样一个命令的最优雅(如上所述)的方法是什么,用户可以提供任何截然不同的截断形式的命令?

解决方法

我提出了以下解决方案,它应该适用于任何解决方案
与bourne兼容的shell:

disambiguate() {
    option="$1"
    shift
    found=""
    all=""
    comma=""
    for candidate in "$@"; do
        case "$candidate" in
            "$option"*)
                found="$candidate"
                all="$all$comma$candidate"
                comma=","
        esac
    done    
    if [ -z "$found" ] ; then
        echo "Unknown option $option: should be one of $@" >&2
        return 1;
    fi
    if [ "$all" = "$found" ] ; then
        echo "$found"
    else
        echo "Ambigious option $option: may be $all" >&2
        return 1
    fi
}    
foo=$(disambiguate "$1" lorem ipsum dolor dollar)
if [ -z "$foo" ] ; then exit 1; fi
echo "$foo"

是的,消除歧义的源代码并不漂亮,但我希望你大部分时间都不必查看此代码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读