bash - 如何使 getopts 忽略未指定的标志(bash)

标签 bash

我有一个脚本,我向其中传递了许多标志。该脚本中仅使用了其中一些标志,我想使用“while getopts”循环它们。然而,似乎这个循环仅在指定所有标志时才有效。但是,某些标志不适用于此脚本,而是传递给另一个脚本,因此我想在这里忽略它们。

while getopts ":W:" flag ; do
   case "${flag}" in 
       "W")
           _TASK=${OPTARG}
           ;;
   esac
done

if [ "${_TASK}" == "OK" ] ; then
   ./other_script.sh "$@"
fi

此代码仅在我像这样运行时才有效:

myscript.sh -W OK -f otherflag1 -g otherflag2 etc...

但如果我运行则不会:

myscript.sh -f otherflag -W OK

因为现在,它不会在循环中找到“-W”标志。因此,传递标志现在取决于顺序,我觉得这很丑陋。 (另外,与此相关:如何从“$@”中删除“-W OK”?)

最佳答案

你可以这样做,但它有点难看,并且有几个警告:

  • 您需要知道如何解析您将传递的标志。例如,如果 -f 标志接受参数,则 -fWOK 需要按原样传递(或作为 -f WOK) ,但如果不是,则 -fWOK-f -W OK 的缩写,您需要应用并删除 -W OK 部分并且仅传递 -f

  • 这意味着其他程序的标志必须采用与 getopts 兼容的格式。这意味着可能没有长选项(例如 --exclude=foo)(嗯,大部分),并且没有像 gnu sed-i 那样奇怪的东西> 标志(它需要一个参数,但它必须直接附加,因此sed -i.bak可以工作,但是sed -i .bak没有)。

  • 这也意味着标志必须位于位置参数之前。或者至少是适用于您的脚本的那些。例如,ls -l somefile.txt 可以,但 ls somefile.txt -l 则不行。

考虑到这些注意事项,这里有一种使用 getopts 来实现的方法。在此示例中,-W 是脚本的一个标志并带有一个参数; -a-b-c-d 是其他程序的标志不要接受争论; -e-f-g 是其他程序确实接受参数的标志:

#!/bin/bash

pass_on=()    # We'll accumulate flags to pass on here
while getopts ":W:abcde:f:g:" flag ; do
        case "${flag}" in
            W )
                echo "got -W '$OPTARG' option" >&2
                _TASK=${OPTARG} ;;

            a|b|c|d )    # pass-on flags that DON'T take arguments
                pass_on+=("-${flag}") ;;

            e|f|g )    # pass-on flags that DO take arguments
                pass_on+=("-${flag}${OPTARG}") ;;

        \? )
            echo "Invalid option: -${OPTARG}" >&2
            exit 1 ;;

        : )
            echo "Missing argument to option -${OPTARG}" >&2
            exit 1 ;;
        esac
done
shift $((OPTIND-1))    # Remove the flags we've processed from the arg list

echo "Passed-on flags and arguments:"
printf " '%s'\n" "${pass_on[@]}" "$@"

关于bash - 如何使 getopts 忽略未指定的标志(bash),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57977984/

相关文章:

linux查找文件并复制到目录

linux - Bash 用字符串替换部分输出

bash - 计算在线 session 的总时间 - 跟进

bash - 如何终止后台/分离的 ssh session ?

bash - sed 不替换行

bash - 扩展变量 Bash 脚本

bash - 如何在 Ubuntu 上启动 `coqide`?

linux - 如何使用 ~ 作为分隔符使用 sed 查找和替换文本

bash - 在 bash 文件中的两行之间添加一行

linux - 从一个系统无密码登录多台 linux 机器的 Shell 脚本