Linux 如何在bash中传递完整的参数列表,同时保持多个单词参数在一起?
我对bash变量扩展中的分词有一些问题。我希望能够将参数列表存储在变量中并运行它,但任何引用的多字参数都无法评估我所期望的效果 我将用一个例子来解释我的问题。假设我有一个函数Linux 如何在bash中传递完整的参数列表,同时保持多个单词参数在一起?,linux,bash,Linux,Bash,我对bash变量扩展中的分词有一些问题。我希望能够将参数列表存储在变量中并运行它,但任何引用的多字参数都无法评估我所期望的效果 我将用一个例子来解释我的问题。假设我有一个函数decho,它在自己的行上打印每个位置参数: #!/bin/bash -u while [ $# -gt 0 ]; do echo $1 shift done 好的,如果我去的话,我会得到: [~]$ decho a b "c d" a b c d 这就是我所期望和想要的。但另一方面,如果我从变量中得到参数列表,
decho
,它在自己的行上打印每个位置参数:
#!/bin/bash -u
while [ $# -gt 0 ]; do
echo $1
shift
done
好的,如果我去的话,我会得到:
[~]$ decho a b "c d"
a
b
c d
这就是我所期望和想要的。但另一方面,如果我从变量中得到参数列表,我会得到:
[~]$ args='a b "c d"'
[~]$ decho $args
a
b
"c
d"
这不是我想要的。我可以去:
[~]$ echo decho $args | bash
a
b
c d
但这似乎有点笨重。有没有更好的方法使decho$args
中的$args
的扩展按我预期的方式进行拆分?您尝试过:
for arg in "$@"
do
echo "arg $i:$arg:"
let "i+=1"
done
应该产生如下结果:
arg 1: a
arg 2: c d
就你而言
直接使用内存,不保证:-)您可以使用:
eval decho $args
嗯<代码>eval decho$args也起作用:
[~]$ eval decho $args
a
b
c d
我可能可以使用
“${array[@]}”
(其工作原理类似于“$@”
)对bash数组执行一些操作,但是我必须编写代码来加载数组,这将是一件痛苦的事情。您可以在脚本中移动eval:
#!/bin/bash -u
eval set -- $*
for i;
do
echo $i;
done
现在您可以执行以下操作:
$ args='a b "c d"'
$ decho $args
a
b
c d
decho "${decho_argv[@]}" # USE DOUBLE QUOTES!!!
但是,如果您在CL上传递参数,则必须引用这些参数:
$ decho 'a b "c d"'
a
b
c d
试图将存储在变量中的参数列表传递给命令从根本上说是有缺陷的 假设您在某个地方有代码来创建包含预期参数的变量。对于命令,则可以将其更改为将参数存储到数组变量中:
decho_argv=(a b 'c d') # <-- easy!
但是,如果您正在尝试获取任意输入,该输入应为与预期命令位置参数相对应的字符串字段,并且希望将这些参数传递给命令,则应将数据读入数组,而不是使用变量
请注意,使用eval来设置带有普通变量内容的位置参数的建议非常危险
因为,在命令行上将变量的内容公开给引号删除和分词操作无法防止变量字符串中的shell元字符造成破坏
例如,假设在下面的示例中,单词“man”被替换为两个单词“rm”和“-rf”,并且最后一个arg单词是“*”:
不要这样做:
> args='arg1 ; man arg4'
> eval set -- $args
No manual entry for arg4
> eval set -- "$args" # This is no better
No manual entry for arg4
> eval "set -- $args" # Still hopeless
No manual entry for arg4
> eval "set -- '$args'" # making it safe also makes it not work at all!
> echo "$1"
arg1 ; man arg4
此函数的执行方式与decho完全相同。问题在于调用decho,而不是decho本身。仅供参考,
echo$1
非常不幸——它用当前目录中的文件名列表替换了*
的参数<代码>回显“$1”不易发生危险。