【问题标题】:Passing arguments with spaces via list in bash通过bash中的列表传递带空格的参数
【发布时间】:2017-04-06 17:32:26
【问题描述】:

我对在 bash 脚本中使用动态生成的参数调用某些函数很感兴趣。

但是,如果某些参数有空格,它似乎不起作用。

让我们有这个测试脚本:

#!/bin/bash
# file uu.sh
[[ -z $1 ]] || echo '$1' $1
[[ -z $2 ]] || echo '$2' $2
[[ -z $3 ]] || echo '$3' $3
[[ -z $4 ]] || echo '$4' $4
[[ -z $5 ]] || echo '$5' $5
[[ -z $6 ]] || echo '$6' $6
[[ -z $7 ]] || echo '$7' $7
[[ -z $8 ]] || echo '$8' $8
[[ -z $9 ]] || echo '$9' $9
[[ -z $0 ]] || echo '$0' $0

任何我的脚本:

#!/bin/bash
# file vv.sh
ARR=(-x)
ARR+=($1)
ARR+=("$1")
ARR+=("'$1'")
ARR+=("\"$1\"")
bash uu.sh ${ARR[*]}
echo
bash uu.sh "${ARR[*]}"

当调用bash vv.sh "a b" 时,我得到以下结果:

$2 -x
$2 a
$3 b
$4 a
$5 b
$6 'a
$7 b'
$8 "a
$9 b"
$0 uu.sh

$1 -x a b a b 'a b' "a b"
$0 uu.sh

我期待一种将变量传递给 uu.sh 的方法,例如结果是:

$1 -x
$2 a b
$0 uu.sh

(我可以直接拨打bash uu.sh -x a\ b,或bash uu.sh -x "a b",或bash uu.sh -x 'a b'

【问题讨论】:

  • 你想要"$1" 而不是$1。你也可以对所有参数使用"$@" ..
  • 问题不在uu.sh 中(无论如何,我用引号测试过,我仍然看到同样的问题)

标签: linux bash shell


【解决方案1】:

您应该有这样的vv.sh 才能将第二个参数中-x 之后的所有参数传递给uu.sh

#!/bin/bash
# file vv.sh
ARR=(-x)    # initialize array with "-x" as first element
ARR+=("$1") # append 1st argument in second element of array
bash uu.sh "${ARR[@]}" # call uu.sh with quoted and [@]

然后将其用作(参见引用的参数):

bash vv.sh "a b"

...将作为输出发出:

$1 -x
$2 a b
$0 uu.sh

【讨论】:

  • 我对传递来自vv.sh 的所有参数不感兴趣,只传递第一个参数(或只是第三个,或其他一些变量)
  • 但是@(和引号)成功了! bash uu.sh "${ARR[@]}"
【解决方案2】:

这是$*$@ 之间的区别,而且,您应该始终引用变量(除非您知道为什么不想要):)

#uu.sh
[[ -z "$1" ]] || echo '$1' "$1"
[[ -z "$2" ]] || echo '$2' "$2"
[[ -z "$3" ]] || echo '$3' "$3"
[[ -z "$4" ]] || echo '$4' "$4"
[[ -z "$5" ]] || echo '$5' "$5"
[[ -z "$6" ]] || echo '$6' "$6"
[[ -z "$7" ]] || echo '$7' "$7"
[[ -z "$8" ]] || echo '$8' "$8"
[[ -z "$9" ]] || echo '$9' "$9"
[[ -z "$0" ]] || echo '$0' "$0"

还有vv.sh

ARR=(-x)
ARR+=($1)
ARR+=("$1")
ARR+=("'$1'")
ARR+=("\"$1\"")

echo 'using quoted ARR[@]'
printf "=%s=\n" "${ARR[@]}"

echo 'using unquoted ARR[@]'
printf "=%s=\n" ${ARR[@]}

echo 'using quoted ARR[*]'
printf "=%s=\n" "${ARR[*]}"

echo 'using unquoted ARR[*]'
printf "=%s=\n" ${ARR[*]}

echo "running UU"
bash uu.sh "${ARR[@]}"

输出:

using quoted ARR[@]
=-x=
=A=
=B=
=A B=
='A B'=
="A B"=
using unquoted ARR[@]
=-x=
=A=
=B=
=A=
=B=
='A=
=B'=
="A=
=B"=
using quoted ARR[*]
=-x A B A B 'A B' "A B"=
using unquoted ARR[*]
=-x=
=A=
=B=
=A=
=B=
='A=
=B'=
="A=
=B"=
running UU
$1 -x
$2 A
$3 B
$4 A B
$5 'A B'
$6 "A B"
$0 uu.sh

【讨论】:

    【解决方案3】:

    "${array[*]}""$*" 扩展为一个单个单词,其中数组成员或位置参数用空格连接。这几乎从来没有用过。而是使用"${array[@]}""$@",它们将所有数组成员展开为分隔单词。 (参见手册中的ArraysSpecial parameters。)

    因此,当您执行bash uu.sh "${ARR[*]}" 时,命令将传递一个字符串作为参数,而bash uu.sh ${ARR[*]} 没有引号,因此数组get split on whitespace 的所有内容。

    【讨论】:

      猜你喜欢
      • 2018-06-24
      • 2021-07-16
      • 2017-06-25
      • 2013-06-10
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-28
      相关资源
      最近更新 更多