【发布时间】:2017-05-02 06:42:31
【问题描述】:
我试图更好地理解如何使用位置参数作为脚本的参数来编写 bash 脚本。具体来说,我想了解如何使脚本尽可能用户友好,能够处理来自任何位置的多个参数。其中ls -lst 与ls -stl 相同。我决定尝试一个密码生成器。我对编写带参数的脚本不是很熟悉。过了一会儿,我决定使用if 语句来完成整个工作。
注意:为了在应得的地方给予功劳,下面脚本中的rand_string函数直接来自this answer。
#!/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
这个脚本有两个可选参数:
任何整数,例如
10、29、54来确定字符串的长度-c或-copy将字符串复制到剪贴板-h或-help显示usage函数
上述任何参数都可以从$1 或$2 位置调用。这些参数中的任何一个也可以省略。
假设脚本被称为password,以下任何一个都是有效用途:
password
password 25
password -c
password 16 -copy
password -c 42
password -help
但脚本本身就是一大堆if 语句。它很长,很乱,很难阅读。
所以我的问题是:如何在不使用这么多 if 语句的情况下,将其编写为采用 有效使用 中显示的相同参数?
我没有要求任何人重写我的脚本。我只是在寻找一些指导,以更好地了解如何正确执行此操作。
【问题讨论】:
-
您是否尝试过考虑
getopts来满足您的要求?它是为此量身定做的 -
感谢您的详细研究,但仍不清楚您想要做什么?您能否提供我们测试所需的最小输入和输出?
-
你认为我应该缩短问题?
-
不完全是缩短它,但让人们更容易理解你正在寻找的代码。例如我想这样做,这样等等。
-
或者给我们一个你想要实现的所有可能的命令行输入的列表
标签: bash shell parameters