如果仅设置一个参数,则修改 bash 参数

如果仅设置一个参数,则修改 bash 参数

我创建了一个脚本与标准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

相关内容