[英]Bash script checking command line parameters
I am still on the learning path of bash, shell, Linux, regex etc. Today I share this bash shell script that I have programmed and that I want to use as a "module" in future scripts. 它彻底测试了一组命令行参数的有效性。 我想请有经验的专家就如何在语法、不同方法或替代命令方面更好地归档内容提供建议和意见。 我尝试了很多不同的方法,但我无法弄清楚。 特别是我不喜欢“案例”结构。 我宁愿定义一组选项字母,例如 'cmds=(hogam)',然后使用 'for c in "${cmds[@]}"; 做'。 但这导致了我必须使用动态变量名的问题,而我无法弄清楚。 另一个问题是,我可以将 boolean 分配为“真”,但我不能用“a=.a”之类的东西来否定它。 等等任何建议都非常欢迎!
#!/bin/bash
# Usage: -p <path> -g <group> -o <owner> -m <mask> -h (help)
# Extensive option and parameter check:
expecting_option=true # alternatingly expecting option switch and parameter on command line
for i do # loop $i trough all parameters
# display help:
if [ $i = "-h" ]; then
echo "Usage:"
echo "-p <path> (default .)"
echo "-o <owner>"
echo "-g <group>"
echo "-m <permission mask> (000 - 777)"
exit
fi;
if [ "$expecting_option" = true ]; then # next arg supposed to be an option
if [[ "$i" =~ ^(.)(.*?)(.*?)$ ]]; then # retrieve up to 3 single characters
# Does it begin with '-' ?
if [ ${BASH_REMATCH[1]} != "-" ]; then
echo "ERROR: Option to begin with '-' expected at '"$i"'" >&2
exit
fi
# only one letter length for options
if [ -n "${BASH_REMATCH[3]}" ]; then
echo "ERROR: Invalid option '"$i"'. Use -h for help" >&2
exit
fi
switch=${BASH_REMATCH[2]} # save the current option switch
# has this option already been set?
# is option valid?
case $switch in
o) if [ $o ]; then
echo 'ERROR: duplicate option: -o' >&2
exit
fi;;
g) if [ $g ]; then
echo 'ERROR: duplicate option: -g' >&2
exit
fi;;
m) if [ $m ]; then
echo 'ERROR: duplicate option: -m' >&2
exit
fi;;
p) if [ $p ]; then
echo 'ERROR: duplicate option: -p' >&2
exit
fi;;
*) echo "ERROR: Invalid option '"$i"'. Use -h for help" >&2
exit;;
esac
fi
# next arg supposed to be the parameter
expecting_option=!true # it's not true, so it works. But is it 'false'?
else # this is supposed to be a parameter for the previous option switch
if [[ "$i" =~ ^\- ]]; then # starts with '-' ?
echo "ERROR: Parameter for "$switch" missing." >&2
exit
fi
case $switch in
o) # check if designated owner exists (=0):
if ! [ $(id -u "$i" > /dev/null 2>&1; echo $?) -eq 0 ]; then
echo "ERROR: user '"$i"' does not exist." >&2
exit
fi
o="$i";;
g) # check if designated group exists:
if [ -z $(getent group "$i") ]; then
echo "ERROR: group '"$i"' does not exist." >&2
exit
fi
g="$i";;
m) if ! [[ $i =~ ^[0-7][0-7][0-7]$ ]]; then
echo "ERROR: Invalid right mask '"$i"'" >&2
exit
fi
m="$i";;
p) # check if path exists
if ! [ -d "${i}" ]; then
echo "ERROR: Directory '"$i"' not found." >&2
exit
fi
p="$i";;
esac
expecting_option=true
fi
done
# last arg must be a parameter:
if [ "$expecting_option" != true ]; then
echo "ERROR: Parameter for "$switch" missing." >&2
exit
fi
# at least o, g or m must be specified:
if ! [ $g ] && ! [ $o ] && ! [ $m ] ; then
# this didn't work: if ! [ [ $g ] || [ $o ] || [ $m ] ] ; then
echo "Nothing to do. Specify at least owner, group or mask. Use -h for help."
exit
fi
# defaults: path = . owner = no change group = no change mask = no change
# set defaults:
[[ -z $p ]] && p="."
# All necessary options are given and checked:
# p defaults to . otherwise valid path
# if o is given, than the user exists
# if g is given, than the group exists
# if m is given, than the mask is valid
# at least one of o,g or m are given
# no option dupes
# no missing parameters
# ok, now let's do something:
# set group:owner + mask of whole directory tree:
if [ $g ] || [ $o ] ; then
[[ -n $g ]] && g=":"$g # use chown's column only if group change required, with or without owner
sudo find $p -type f -exec chown $o$g {} + &&
sudo find $p -type d -exec chown $o$g {} +
fi
if [ $m ]; then
sudo find $p -type f -exec chmod $m {} + &&
sudo find $p -type d -exec chmod $m {} +
fi
正如@Shawn 在评论中所建议的那样,使用“getopts”,解析将变为:
# Default values for options
g=
o=
P=.
m=
while getopts g:o:p:m: opt ; do
case "$opt" in
g) g=$OPTARG ;;
o) o=$OPTARG ;;
p) p=$OPTARG ;;
m) m=$OPTARG ;;
# Abort on illgal option
*) exit 2 ;;
esac
done
shift $((OPTIND-1))
# Rest of code goes here
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.