奇怪的Getopt(一)解析行为
Odd Getopt (1) parsing behavior
使用 getopt (1) 解析 bash 中的一些选项,当我从 cmd 行向它传递选项时它没有评估。它默认为 --) "double dash" case 语句并在我提供其他选项时传递它们,不确定为什么会导致这种奇怪的行为,代码如下:
parse_args() {
cmd="" # Default none
isparsed=0 # If args parsed = 1
# Check the number of arguments. If none are passed, print help and exit
options=$(getopt -o hs:d:c:p:i: -l help,source:,destination:,connection:,platform:,install: -n "cdr" -- "$@")
# If the number of arguments after processing them using getopt is larger
# than zero, then it means there is an unknown argument.
if [[ $? -ne 0 ]]; then
HELP
exit 1
fi
printdbg "parsing options"
eval set -- "$options"
while true; do
case "" in
-h) # Show help option menu
HELP
exit 1
;;
-s|--source) # Parse options to source sub command
cmd= # Remove 'source' from the argument list
shift;
if [[ $cmd == "sqlite" ]]; then
SOURCE="sqlite"
elif [[ $cmd == "mysql" ]]; then
SOURCE="mysql"
else
HELP
exit 1
fi
isparsed=1
;;
-d|--destination) # Parse options to destination sub command
cmd= # Remove 'destination' from the argument list
shift;
if [[ $cmd == "postgre" ]]; then
DESTINATION="postgre"
elif [[ $cmd == "riak" ]]; then
DESTINATION="riak"
elif [[ $cmd == "both" ]]; then
DESTINATION="both"
else
HELP
exit 1
fi
isparsed=1
;;
-c|--connection) # Parse options to connection sub command
cmd= # Remove 'connection' from the argument list
shift; printdbg "$cmd"
if [[ ! -z $cmd ]]; then
SOURCE_CONN=$(echo "$cmd" | awk -F "::" '{print }')
DESTINATION_CONN=$(echo "$cmd" | awk -F "::" '{print }')
parse_csv "$SOURCE_CONN" #stored in PARSED_ARR
echo ${PARSED_ARR[@]}
# ${DESTINATION_CONN:=${PARSED_ARR}}
else
HELP
exit 1
fi
isparsed=1
;;
-p|--platform) # Parse options to platform sub command
cmd= # Remove 'platform' from the argument list
shift;
if [[ $cmd == "csv" ]]; then
CDR_TYPE=1
elif [[ $cmd == "api" ]]; then
CDR_TYPE=2
elif [[ $cmd == "freeswitch" ]]; then
CDR_TYPE=3
elif [[ $cmd == "asterisk" ]]; then
CDR_TYPE=4
elif [[ $cmd == "yate" ]]; then
CDR_TYPE=5
elif [[ $cmd == "kamailio" ]]; then
CDR_TYPE=6
elif [[ $cmd == "opensips" ]]; then
CDR_TYPE=7
elif [[ $cmd == "sipwise" ]]; then
CDR_TYPE=8
elif [[ $cmd == "veraz" ]]; then
CDR_TYPE=9
else
HELP
exit 1
fi
isparsed=1
;;
-i|--install) # Parse options to install sub command
cmd= # Remove 'install' from the argument list
shift;
if [[ $cmd == "sqlite" ]]; then
install_dependencies
install_sqlite
elif [[ $cmd == "mysql" ]]; then
install_dependencies
install_mysql
elif [[ $cmd == "postgre" ]]; then
install_dependencies
install_postgre
elif [[ $cmd == "riak" ]]; then
printwarn "This feature will be supported in future versions"
exit 1
elif [[ $cmd == "pusher" ]]; then
install_dependencies
install_golang
install_cdrpusher
install_supervisord
elif [[ $cmd == "stats" ]]; then
install_dependencies
install_golang
install_cdrstats
else
HELP
exit 1
fi
isparsed=1
;;
--)
shift
break
;;
esac
done
}
我可以看出它默认为 case 语句中的那个点,因为 isparsed 标志仍未设置 (== 0),我从 main()
将错误打印到控制台
main() {
. cdr_funcs
check_permissions
detect_os
parse_args
if [[ ${isparsed} == 1 ]]; then
INSTALL_COMPLETE_MESG
exit 0
fi
printerr "isparsed flag == 0"
HELP
exit 1
}
运行 -h 标志公然显示:
devbox cdr # ./cdr -h
[DEBUG] [check_permissions]: Root Permissions Validated
[DEBUG] [detect_os]: Starting OS Platform detection
[DEBUG] [detect_os]: Checking OS Compatibility
[DEBUG] [detect_os]: OS detected: [linux] (OS is supported)
[DEBUG] [detect_os]: Finished OS detection
[DEBUG] [parse_args]: parsing options
[ERROR] [main]: isparsed flag == 0
在函数 (parse_args
) 中,"$@"
扩展为函数调用的参数,而不是封闭脚本。没有任何参数,因此 getopt
看不到任何参数,也不会产生任何选项。
如果你想用函数分析脚本参数,你需要将它们提供给函数:
parse_args "$@"
使用 getopt (1) 解析 bash 中的一些选项,当我从 cmd 行向它传递选项时它没有评估。它默认为 --) "double dash" case 语句并在我提供其他选项时传递它们,不确定为什么会导致这种奇怪的行为,代码如下:
parse_args() {
cmd="" # Default none
isparsed=0 # If args parsed = 1
# Check the number of arguments. If none are passed, print help and exit
options=$(getopt -o hs:d:c:p:i: -l help,source:,destination:,connection:,platform:,install: -n "cdr" -- "$@")
# If the number of arguments after processing them using getopt is larger
# than zero, then it means there is an unknown argument.
if [[ $? -ne 0 ]]; then
HELP
exit 1
fi
printdbg "parsing options"
eval set -- "$options"
while true; do
case "" in
-h) # Show help option menu
HELP
exit 1
;;
-s|--source) # Parse options to source sub command
cmd= # Remove 'source' from the argument list
shift;
if [[ $cmd == "sqlite" ]]; then
SOURCE="sqlite"
elif [[ $cmd == "mysql" ]]; then
SOURCE="mysql"
else
HELP
exit 1
fi
isparsed=1
;;
-d|--destination) # Parse options to destination sub command
cmd= # Remove 'destination' from the argument list
shift;
if [[ $cmd == "postgre" ]]; then
DESTINATION="postgre"
elif [[ $cmd == "riak" ]]; then
DESTINATION="riak"
elif [[ $cmd == "both" ]]; then
DESTINATION="both"
else
HELP
exit 1
fi
isparsed=1
;;
-c|--connection) # Parse options to connection sub command
cmd= # Remove 'connection' from the argument list
shift; printdbg "$cmd"
if [[ ! -z $cmd ]]; then
SOURCE_CONN=$(echo "$cmd" | awk -F "::" '{print }')
DESTINATION_CONN=$(echo "$cmd" | awk -F "::" '{print }')
parse_csv "$SOURCE_CONN" #stored in PARSED_ARR
echo ${PARSED_ARR[@]}
# ${DESTINATION_CONN:=${PARSED_ARR}}
else
HELP
exit 1
fi
isparsed=1
;;
-p|--platform) # Parse options to platform sub command
cmd= # Remove 'platform' from the argument list
shift;
if [[ $cmd == "csv" ]]; then
CDR_TYPE=1
elif [[ $cmd == "api" ]]; then
CDR_TYPE=2
elif [[ $cmd == "freeswitch" ]]; then
CDR_TYPE=3
elif [[ $cmd == "asterisk" ]]; then
CDR_TYPE=4
elif [[ $cmd == "yate" ]]; then
CDR_TYPE=5
elif [[ $cmd == "kamailio" ]]; then
CDR_TYPE=6
elif [[ $cmd == "opensips" ]]; then
CDR_TYPE=7
elif [[ $cmd == "sipwise" ]]; then
CDR_TYPE=8
elif [[ $cmd == "veraz" ]]; then
CDR_TYPE=9
else
HELP
exit 1
fi
isparsed=1
;;
-i|--install) # Parse options to install sub command
cmd= # Remove 'install' from the argument list
shift;
if [[ $cmd == "sqlite" ]]; then
install_dependencies
install_sqlite
elif [[ $cmd == "mysql" ]]; then
install_dependencies
install_mysql
elif [[ $cmd == "postgre" ]]; then
install_dependencies
install_postgre
elif [[ $cmd == "riak" ]]; then
printwarn "This feature will be supported in future versions"
exit 1
elif [[ $cmd == "pusher" ]]; then
install_dependencies
install_golang
install_cdrpusher
install_supervisord
elif [[ $cmd == "stats" ]]; then
install_dependencies
install_golang
install_cdrstats
else
HELP
exit 1
fi
isparsed=1
;;
--)
shift
break
;;
esac
done
}
我可以看出它默认为 case 语句中的那个点,因为 isparsed 标志仍未设置 (== 0),我从 main()
将错误打印到控制台main() {
. cdr_funcs
check_permissions
detect_os
parse_args
if [[ ${isparsed} == 1 ]]; then
INSTALL_COMPLETE_MESG
exit 0
fi
printerr "isparsed flag == 0"
HELP
exit 1
}
运行 -h 标志公然显示:
devbox cdr # ./cdr -h
[DEBUG] [check_permissions]: Root Permissions Validated
[DEBUG] [detect_os]: Starting OS Platform detection
[DEBUG] [detect_os]: Checking OS Compatibility
[DEBUG] [detect_os]: OS detected: [linux] (OS is supported)
[DEBUG] [detect_os]: Finished OS detection
[DEBUG] [parse_args]: parsing options
[ERROR] [main]: isparsed flag == 0
在函数 (parse_args
) 中,"$@"
扩展为函数调用的参数,而不是封闭脚本。没有任何参数,因此 getopt
看不到任何参数,也不会产生任何选项。
如果你想用函数分析脚本参数,你需要将它们提供给函数:
parse_args "$@"