解析 bash 中具有 space 的单个字符串参数

Parsing single string argument that has space in bash

将单个字符串参数(中间有 space)解析为 bash 脚本的最佳方法是什么?

#!/bin/bash

eval $@
echo $OPT1
echo $OPT2
echo $OPT3
echo $OPT4

eval works fine when the options are of one word like below

./args.sh 'OPT1=1 OPT2=2 OPT3=3 OPT4=4'
 1 2 3 4

但当我的论点如下所示时就不会了

./args.sh 'OPT1=1 OPT2=2 OPT3=3.1 3.2 OPT4=4'

解析上述参数的更好方法是什么?

请注意,我无法控制输入参数,我使用的是第三方二进制文件,它只是将这些参数生成为单个字符串。

是否有任何类似于 eval 的命令将根据我的情况下的某个定界符进行解析'='

eval 总是危险的。幸运的是,有一种更安全可靠的方法来定义变量,那就是使用 declare.

试试这个脚本:

$ cat args.sh
#!/bin/bash
old=$IFS
IFS=$'\n'
declare "$(sed -E 's/ +([[:alnum:]]+=)/\n/g' <<<"$*")"
IFS=$old

#Verify that declare was succesful:
declare -p OPT1 OPT2 OPT3 OPT4

我们可以 运行 脚本来验证它是否按预期工作:

$ ./args.sh 'OPT1=1 OPT2=2 OPT3=3.1 3.2 OPT4=4'
declare -- OPT1="1"
declare -- OPT2="2"
declare -- OPT3="3.1 3.2"
declare -- OPT4="4"

工作原理

  • #!/bin/bash

    此 shebang 行将 bash 指定为 shell

  • old=$IFS

    这会保存 IFS 的旧值。

  • IFS=$'\n'

    这会将 IFS 设置为换行符。

  • declare "$(sed -E 's/ +([[:alnum:]]+=)/\n/g' <<<"$*")"

    sed 命令重新格式化输入以将每个声明放在单独的行中。输出适合作为 declare.

  • 的参数
  • IFS=$old

    这将恢复 IFS 的旧值。

  • declare -p OPT1 OPT2 OPT3 OPT4

    这是一个诊断语句,因此我们可以验证变量是否已按照我们的需要定义。