我创建了一个脚本与标准getopt
魔法,这样你就可以调用脚本
batman-connect -c ffki
如何添加一个选项来仅使用一个选项而不使用破折号来调用此脚本?
batman-connect ffki
所以它会将这个唯一的选项解释为-c
?的第二个参数。
根据这个答案我试过:
if [ $@ = "ffki" ]; then
set -- "-c $@"
fi
但这会产生错误,我认为因为我的这一行脚本将其改回:
# Execute getopt on the arguments passed to this program, identified by the special character $@
PARSED_OPTIONS=$(getopt -n "$0" -o hsrvVi:c: --long "help,start,restart,stop,verbose,vv,version,interface:,community:" -- "$@")
我不喜欢重新安排我的整个脚本,那么是否有一个简单的单行代码可以将第一个参数设置为“-c”,第二个参数设置为“ffki”?
答案1
你可以做类似的事情
if [ $# = 1 ]; then
# do whatever you'd do when there is only one argument
else
# do the getopt bits
fi
# do what you'd do in either case
如果 -c 是您想要支持的唯一开关,那么您不需要 getopt 并且可以执行如下操作:
#!/bin/bash
usage() {
echo "Usage: $0 [ -c ] arg" >&2
exit 1
}
if [ $# = 2 ]; then
if [ $1 = "-c" ]; then
shift
c_switch_value="$1"
else
usage
fi
elif [ $# = 1 ]; then
c_switch_value="$1"
else
usage
fi
但这是否更具可读性还有待商榷。
答案2
我在这个脚本的开头添加了:
if [ $# = 1 ]; then
# If there is only one argument, replace the current process with the new invocation of the script
# the only option will be used as -c option
exec "$0" -c "$@"
fi
这并没有回答最初的问题,但它是一种解决方法,适用于我的特殊情况。
答案3
if [ $@ = "ffki" ]; then
子句中的命令if
扩展为 ,[
后跟构成位置参数的单词的通配符扩展列表,后跟单词=
ffki
]
。一般来说,当它在双引号之外时,$VAR
并不意味着“的值VAR
”,它的意思是“将值分成VAR
单独的单词并将它们解释为通配符”。看为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?
此外"$@"
还有一个特殊情况:它扩展为位置参数列表(无需进一步扩展),而不是单个单词(尽管有引号)。您可以使用"$*"
,它扩展为由用空格分隔的位置参数组成的单个单词(更准确地说,由 值的第一个字符分隔IFS
)。因此,要测试是否存在值为 的单个位置参数ffki
,您可以使用
if [ "$*" = "ffki" ]; then
或者,您可以计算位置参数的数量并单独测试它们的值。例如,如果您希望允许值包含空格,则这是必要的。
if [ $# -eq 1 ] && [ "$1" = "ffki" ]; then
要更改位置参数,您已经很接近了:使用set
内置函数,并将新的位置参数集作为单独的参数传递。如果存在第一个参数以 开头的风险-
,请使用它set -- …
,以免将其解释为选项。
if [ "$*" = "ffki" ]; then
set -- -c "ffki"
fi
答案4
你可能想要这样的东西:
# getopt code that sets "$c_value" goes here ...
# ... then
if [[ -z $c_value ]] && (( $# > 0 )); then
c_value=$1
shift
fi