Bash 使用位置参数代替if语句

Bash 使用位置参数代替if语句,bash,shell,parameters,Bash,Shell,Parameters,我试图更好地理解如何使用位置参数作为脚本的参数来编写bash脚本。具体来说,我想了解如何使脚本尽可能友好,能够处理来自任何位置的多个参数。在这方面,ls-lst与ls-stl基本相同。我决定尝试一个密码生成器。我不太熟悉编写包含参数的脚本。过了一会儿,我决定用if语句来完成整个过程 注意:要在需要评分的地方评分,下面脚本中的rand\u string函数直接来自。 #!/bin/bash ## grep -v '##' will remove all the comments if you'r

我试图更好地理解如何使用位置参数作为脚本的参数来编写bash脚本。具体来说,我想了解如何使脚本尽可能友好,能够处理来自任何位置的多个参数。在这方面,
ls-lst
ls-stl
基本相同。我决定尝试一个密码生成器。我不太熟悉编写包含参数的脚本。过了一会儿,我决定用
if
语句来完成整个过程

注意:要在需要评分的地方评分,下面脚本中的
rand\u string
函数直接来自。

#!/bin/bash

## grep -v '##' will remove all the comments if you're so inclined :)
usage(){
echo "usage: $0 [n][-c]||[-h]"  
}

## Character set used to create random strings 
chars=( {a..z} {A..Z} {0..9} \! \" \# \$  \% \& \( \) \* \+ \, \- \. \/ \: \; \< \= \> \? \@ \[ \] \^ \_ \` \{ \| \} \~ \\ )

## Create random string from character set
rand_string() { 
    local c=$1 ret=
    while((c--)); do
        ret+=${chars[$((RANDOM%${#chars[@]}))]}; done
    printf '%s\n' "$ret"
}

## get a random number between 14-50
length() {
    python -S -c "import random; print random.randrange(14,50)"
}

## regular expression to test for valid numbers
re='^[0-9]+$'

## if no options specified 
## create a random string of charcters
## of a random length between 14-50 characters
## display password on screen and exit
if [ ! "$1" ]; then
    set - "$(length)"
    password="$(rand_string "$1")"
    echo "$password"
    exit
fi

## if option 1 or option 2 is -h or -help
## display usage and exit
if [[ "$1" == -h || "$1" == -help || "$2" == -h || "$2" == -help ]]; then
    usage
    exit
fi

## if more than 2 options
## exit with error code 1
if [[ $# -gt 2 ]]; then
    echo "Invalid number of options specified"
    usage
    exit 1
fi
## if exactly 2 options
if [[ $# -eq 2 ]]; then
    ## test if option 1 is a number
    ## if option 1 is NOT a number 
    if [[ ! "$1" =~ $re ]]; then
        ## test if option 1 is -c or -copy
        if [[ "$1" == -c || "$1" == -copy ]]; then
            ## if option 1 is -c or -copy
            ## test if option 2 is a number
            ## if 2 is a number and 1 is -c or -copy 
            ## execute the command
            if [[ "$2" =~ $re ]]; then
                set - "$(length)"
                rand_string "$1" | pbcopy
                echo "Password copied to clipboard"
                exit
            ## if option 1 is -c or -copy
            ## but option 2 is NOT a number
            ## exit script with error code 1
            elif [[ ! "$2" =~ $re ]]; then
                echo "Unrecognized option \"$2\""
                usage
                exit 1
            fi
        else
            echo "Unrecognized option \"$1\""
            exit 1
        fi
    ## if option 1 is a number
    elif [[ "$1" =~ $re ]]; then
        ## and option 2 is -c or -copy
        ## execute the command
        if [[ "$2" == -c || "$2" == -copy ]]; then
            rand_string "$1" | pbcopy
            echo "Password copied to clipboard"
            exit
        ## if option 1 is a number 
        ## but option 2 is not -c or -copy
        ## exit script with error code 1
        else
            echo "Unrecognized option \"$2\""
            usage
            exit 1
        fi
    fi
## if exactly one option specified
elif [[ $# -eq 1 ]]; then
    ## if option is NOT a number
    ## check if option is -c or -copy
    if [[ ! "$1" =~ $re ]]; then
        ## if option is -c or -copy
        ## execute the command 
        if [[ "$1" == -c || "$1" == -copy ]]; then
            set - "$(length)"
            rand_string "$1" | pbcopy
            echo "Password copied to clipboard"
            exit
        ## if option is neither a number nor -c or -copy
        ## exit script with error code 1
        else
            echo "Unrecognized option \"$1\""
            usage
            exit 1
        fi
    ## if option is a number
    ## execute the command
    elif [[ "$1" =~ $re ]]; then
        rand_string "$1"
    fi
fi
#/bin/bash
##grep-v“##”将删除所有注释,如果您愿意的话:)
用法(){
echo“用法:$0[n][c]|[h]”
}
##用于创建随机字符串的字符集
字符=({a..z}{a..z}{0..9}\!“\\\\$\%\&(\)\*\+\,\-\.\/\:\;\\\=\>\?\[\]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
##从字符集创建随机字符串
rand_string(){
本地成本=1美元租金=
当((c-);做
ret+=${chars[$((随机%${#chars[@]}))]};完成
printf“%s\n”$ret
}
##获取14-50之间的随机数
长度(){
python-S-c“随机导入;随机打印.randrange(14,50)”
}
##用于测试有效数字的正则表达式
re='^[0-9]+$'
##如果未指定选项
##创建一个随机字符字符串
##14-50个字符之间的随机长度
##在屏幕上显示密码并退出
如果[!“$1”];则
集合-“$(长度)”
password=“$(随机字符串“$1”)”
回显“$password”
出口
fi
##如果选项1或选项2为-h或-help
##显示使用情况并退出
如果[[“$1”==-h | |“$1”=-help | |“$2”=-h | | |“$2”=-help];则
使用
出口
fi
##如果超过2个选项
##退出,错误代码为1
如果[$#-gt 2]];则
echo“指定的选项数无效”
使用
出口1
fi
##如果正好有两个选项
如果[$#-eq 2]];则
##测试选项1是否为数字
##如果选项1不是一个数字
如果[[!“$1”=~$re]],则
##测试选项1是-c还是-copy
如果[[“$1”==-c | |“$1”==-copy]];则
##如果选项1为-c或-copy
##测试选项2是否为数字
##如果2是数字,1是-c或-copy
##执行命令
如果[[“$2”=~$re]];则
集合-“$(长度)”
rand_字符串“$1”| pbcopy
回显“密码已复制到剪贴板”
出口
##如果选项1为-c或-copy
##但选项2不是一个数字
##退出脚本,错误代码为1
elif[!“$2”=~$re]];然后
回显“无法识别的选项\”“2美元”
使用
出口1
fi
其他的
回显“无法识别的选项\”“1美元”
出口1
fi
##如果选项1是一个数字
elif[[“$1”=~$re]];然后
##选项2是-c或-copy
##执行命令
如果[[“$2”==-c | |“$2”==-copy]];那么
rand_字符串“$1”| pbcopy
回显“密码已复制到剪贴板”
出口
##如果选项1是一个数字
##但选项2不是-c或-copy
##退出脚本,错误代码为1
其他的
回显“无法识别的选项\”“2美元”
使用
出口1
fi
fi
##如果只指定了一个选项
elif[$#-eq 1];然后
##如果选项不是一个数字
##检查选项是-c还是-copy
如果[[!“$1”=~$re]],则
##如果选项为-c或-copy
##执行命令
如果[[“$1”==-c | |“$1”==-copy]];则
集合-“$(长度)”
rand_字符串“$1”| pbcopy
回显“密码已复制到剪贴板”
出口
##如果选项既不是数字也不是-c或-copy
##退出脚本,错误代码为1
其他的
回显“无法识别的选项\”“1美元”
使用
出口1
fi
##如果选项是一个数字
##执行命令
elif[[“$1”=~$re]];然后
兰特字符串“$1”
fi
fi
此脚本接受两个可选参数:

  • 用于确定字符串长度的任意整数,如..
    10
    29
    54

  • -c
    -copy
    将字符串复制到剪贴板

  • -h
    -help
    显示
    用法
    功能

可以从
$1
$2
位置调用上述任何参数。这些参数中的任何一个也可以省略

假设脚本名为
password
,则以下任何一项都是有效使用

密码

密码25

密码-c

密码16-复制

密码-c42

密码-帮助

但是脚本本身就是一堆乱七八糟的
if
语句,冗长、凌乱且难以阅读

所以我的问题是:如果不使用这么多的
if
语句,如何编写它来接受valid uses中显示的相同参数


我没有要求任何人重写我的脚本。我只是想寻求一些指导,以便更好地理解如何正确地执行此操作。

如果您不想使用
getopts
,那么简单的方法就是移动
参数

#!/bin/bash

usage(){
        echo "usage: $0 [n][-c]||[-h]" >&2
        exit 1
}

declare copy=
declare argument=

while [ "$1" ]; do
        case "$1" in
                -h|-help)
                        usage
                        ;;

                -c|-copy)
                        copy=1
                        ;;

                *)
                        [[ "$1" =~ ^[0-9]+$ ]] || usage
                        argument="$1"
                        ;;
        esac
        shift
done

[ "$argument" ] || argument=$(length)

if [ "$copy" ]; then
        rand_string "$argument" | pbcopy
else
        rand_string "$argument"
fi

你有没有试着根据你的要求考虑
getopts
?这是专门为这一点设计的感谢你的详细研究,但仍然不清楚你想做什么?你能给出我们测试所需的最小输入和输出吗?你认为我应该缩短这个问题吗?不完全缩短它,但让人们更容易理解等待你正在寻找的代码。例如,我想做t