shell脚本通过空格传递参数

chr*_*007 2 parameters bash shell space

我有以下脚本(示例):

#!/bin/bash
while getopts a: opt; do
    case "$opt" in
        a) val="$OPTARG";;
        ?) echo "use the flag \"-a\""
           exit 2;;
    esac
done
echo "a specified with: ${val}"  
Run Code Online (Sandbox Code Playgroud)

当我现在调用此脚本时,test.sh -a "here is a string"输出为:a specified with: here不是我想要的那样a specified with: here is a string

test.sh -a here\ is\ a\ string我知道我可以用or调用脚本,test.sh -a "here\ is\ a\ string"它会起作用。但就我而言,我无法操纵我想要传递的字符串。
那么我怎样才能改变我的getopts功能以使其正常工作呢?

我也尝试过getopt,但我的工作更糟糕:

commandsShort="a:"
commandsLong="aval:"
TEMP=`getopt \
        -o $commandsShort \
        -l $commandsLong \
        -q \
        -n "$0" -- "$@"`
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

gho*_*oti 5

这在您的问题的评论中得到了解决。:-)

您正在使用以下命令调用脚本:

eval "test.sh $@"
Run Code Online (Sandbox Code Playgroud)

如果您选择“here is a string”,则此“eval”行的效果是创建引号中的命令行:

test.sh here is a string
Run Code Online (Sandbox Code Playgroud)

评估它。

根据附加评论,如果您可以避免评估,那么您应该这样做。

也就是说,如果您需要它,您可以随时引用 eval 中的字符串:

eval "test.sh \"$@\""
Run Code Online (Sandbox Code Playgroud)

或者,如果您不喜欢转义引号,请使用单引号,因为$@由于外引号是双引号,您的引号将被扩展:

eval "test.sh '$@'"
Run Code Online (Sandbox Code Playgroud)

最后,正如您在评论中提到的,直接运行可能是最好的选择:

test.sh "$@"
Run Code Online (Sandbox Code Playgroud)

请注意,如果您$@包含该-a选项,您可能会遇到新问题。考虑命令行:

test.sh "-a here is a string"
Run Code Online (Sandbox Code Playgroud)

在这种情况下,以 开头的整个字符串都-a可以在 中找到$1,并且您将没有 getopts 选项,也没有 OPTARG。