具有多个标志的脚本

具有多个标志的脚本

我正在尝试创建一个小写/大写文件或目录的脚本。

 modify [-r] [-l|-u] <dir/file names...>

我目前正在使用 getopts 来检查标志。但是,我无法运行像修改 -rl 那样递归地小写我的目录/文件的命令。

(编辑)代码:

#!/bin/bash

FLAGS=""
if [ $# -eq 0 ]
then
    echo -e "No arguments supplied. \nPlease supply an argument.For more information use -h."
else
  while getopts "rluh" opt
  do
    case $opt in
      r)
        FLAGS+=r
        ;;
      l)
        FLAGS+=l
        ;;
      u)
        FLAGS+=u
        ;;
      h)
        FLAGS+=h
        ;;
      *)
        echo "Unrecognized argument. Please enter -h for information"
    esac
  done

fi
if [[ "$FLAGS" == "l" && "$2" -eq 0 ]]
then
  echo "file to modify $2"
elif [[ "$FLAGS" == "h" && "$2" -eq 0 ]] 
then
  echo "Some info"
fi


exit 0

答案1

如果为每个激活的选项设置单独的标志会更容易,这样您就不需要再解析另一个字符串来检查是否使用了某个选项。

例如:

#!/bin/bash

self=$0

show_help () {
    cat <<END_HELP
Usage: $self [-r] [-l|-u] pathname [...]

Options:

    info about options here

END_HELP
}

recurse=0    # don't recurse by default
lowercase=1  # lowercase by default

while getopts rluh opt; do
    case $opt in
        r) recurse=1   ;;
        l) lowercase=1 ;;
        u) lowercase=0 ;;
        h) show_help
           exit ;;
        *) echo 'Error in parsing options' >&2
           exit 1
    esac
done

shift "$(( OPTIND - 1 ))"

for pathname do
    if [ -d "$pathname" ] && [ "$recurse" -eq 1 ]; then
        # recurse here
    fi
    if [ "$lowercase" -eq 1 ]; then
        # turn into lowercase
    else
        # turn into uppercase
    fi
done

请注意,后面的代码shift只是示例代码。我建议您考虑使用循环来代替find递归(可能在所有情况下,即使recursion标志不是放)。

顺便说一句shift, 删除了所有已解析的选项,"$@"以便只有路径名操作数保留在位置参数列表中。这就是循环之后迭代的内容。

上面编写的代码使用合理的默认值(这些应该在帮助文本中提及)。这意味着无需任何选项即可运行脚本。作为旁注,运行该工具任何参数都可能不会导致错误。没有工作要做,所以不应该做任何工作。

答案2

您将标志字母连接到单个字符串,因此使用myscript -l -r,您会得到FLAGS=lr,它不等于lr

您可以使用模式匹配而不是相等测试来处理这个问题:

if [[ $FLAGS = *r* ]]; then
    echo "flag -r was given"

或为每个标志添加不同的变量:

r_flag=
l_flag=
while getopts "rluh" opt; do
    case $opt in
        r) r_flag=1;;
...
if [[ $r_flag ]]; then
    echo "flag -r was given"

无论如何,您很可能希望在循环shift $(( OPTIND - 1 ))之后执行while getopts,以便从位置参数中删除 , ... 处理的选项,而, ...getopts中剩下的是选项之后给出的脚本参数。$1$2

答案3

类似的东西FLAGS+=r会将 r 附加到 FLAGS 上。对于modify -r -lFLAGS 因此将是rl。每个选项应该使用一个变量 ( FLAG_r)。

仅当脚本"$2" -eq 0获取两个目录名称(第二个为0.更好的比较是"$2" = ""

相关内容