Bash 使用位置参数代替if语句
我试图更好地理解如何使用位置参数作为脚本的参数来编写bash脚本。具体来说,我想了解如何使脚本尽可能友好,能够处理来自任何位置的多个参数。在这方面,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
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