Bash getopts,参数没有被传递给选项

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bash getopts,参数没有被传递给选项相关的知识,希望对你有一定的参考价值。

我有以下脚本应该像这样工作:

bash code.sh -u user -g

它应该返回输入用户的组,而是返回正在执行脚本的用户组。

    #!/bin/bash

while getopts u:fgd options; do
    case $options in
    u)
    user = $OPTARG 2>/dev/null;
    if grep -q $OPTARG /etc/passwd == 1 2>/dev/null ; 
    then
      echo "user exists";

    else
      echo "user doesnt exist"
    fi 
    ;;
    g) if $user;
    then    
        echo $user;
        echo "the groups of the user are: ";
        groups $user ;
    else
        echo "user missing"
    fi 
    ;;
    f) echo "output f" ;;

    d) echo "output d" ;;


    esac

done

基本上在g)如果有一个估算的用户应该工作,用户不是明亮地被抓住作为参数

答案

以下是代码的注释版本:

#!/bin/bash

while getopts u:fgd options; do
    case $options in
    u)
    user = $OPTARG 2>/dev/null;    # no spaces around the assignment, it is not set
                                   # even if it worked, you still have a problem
                                   # user is always set, even if the user does not
                                   # exist but you want to test if the variable is
                                   # set later, you should move this into the if
    if grep -q $OPTARG /etc/passwd == 1 2>/dev/null ; # your test does not work,
                                                      # if does test the return value
                                                      # of the command directly, not
                                                      # with a '== 1'
                                                      # also this grep pattern will
                                                      # match more than users
# also, a return code of 1 (or any non-zero value) means failure

    then
      echo "user exists";

    else
      echo "user doesnt exist"
    fi 
    ;;
    g) if $user;   # here you want to check if user is set, but bash
                   # will try to run the content of user and test the return
                   # value. Since user was not set above, it will be empty and 
                   # return no error. After that, the command groups will be called
                   # with an empty value and return your own groups.
    then    
        echo $user;
        echo "the groups of the user are: ";
        groups $user ;
    else
        echo "user missing"
    fi 
    ;;
    f) echo "output f" ;;

    d) echo "output d" ;;


    esac

done

以下是您希望它做的事情:

#!/bin/bash
set -euo pipefail    # this is what can be called bash strict mode
                     # it will make bash exit with an error if any
                     # command return non-zero, even in pipe or if
                     # a variable is undefined

user="" # define the variable as empty

while getopts u:fgd options; do
    case "$options" in
        u)
            if grep -q "^$OPTARG:" /etc/passwd ; then # note the '^' to make sure the
                                                     # string starts at the beginning
                                                     # of the line
                user="$OPTARG"              # store the value, otherwise remain empty
                echo "user exists"
            else
                echo "user doesnt exist"
            fi
        ;;
        g)
            if [ -n "$user" ] ; then          # check if the string is non-zero length
                echo "$user"
                echo "the groups of the user are: "
                groups "$user" 
            else
                echo "user missing"
            fi 
        ;;
        f) echo "output f" ;;

        d) echo "output d" ;;
        *) echo "error, invalid option $options" ;; # handle the default case
    esac
done

我还强烈建议通过bash -x查看你的代码,它会在运行时打印出每个命令。

以上是关于Bash getopts,参数没有被传递给选项的主要内容,如果未能解决你的问题,请参考以下文章

在 Bash 中使用 getopts 检索单个选项的多个参数

具有多个强制性选项的 bash getopts

Bash getopts:识别否定选项(-x- 或 +x)?

如何在 Bash 中使用 getopt 和长选项?

如何使用内置 Bash getopts 的长选项?

使用 getopt 处理命令行长参数