繁体   English   中英

我如何在bash中传递完整的参数列表,同时将多字参数保持在一起?

[英]How can I pass a complete argument list in bash while keeping mulitword arguments together?

我在bash变量扩展中遇到单词拆分问题。 我希望能够将参数列表存储在变量中并运行它,但是任何带引号的多字参数都无法评估我的期望。

我将用一个例子来解释我的问题。 可以说我有一个函数decho ,它在自己的行上打印了每个位置参数:

#!/bin/bash -u
while [ $# -gt 0 ]; do
  echo $1
  shift
done

好吧,如果我去decho ab "cd"我得到:

[~]$ 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扩展按我期望的方式拆分?

您可以使用:

eval decho $args

您可以在脚本内移动评估:

#!/bin/bash -u
eval set -- $*
for i; 
do 
  echo $i;
done

现在您可以执行以下操作:

$ args='a b "c d"'
$ decho $args
a
b
c d

但是如果在CL上传递参数,则必须引用这些参数:

$ decho 'a b "c d"'
a
b
c d

从根本上说,试图将存储在变量中的参数列表传递给命令是有缺陷的。

大概,如果您在某处有代码来创建一个包含预期参数的变量。 对于命令,则可以将其更改为将args存储到数组变量中:

decho_argv=(a b 'c d')  # <-- easy!

然后,可以执行以下操作,而不是更改命令“ decho”以容纳从普通变量中获取的args(这将破坏其处理常规args的能力):

decho "${decho_argv[@]}"  # USE DOUBLE QUOTES!!!

但是,如果您正在尝试采用任意输入(预期是与预期的命令位置参数相对应的字符串字段)的情况,并且想要将这些参数传递给命令,则应该使用变量而不是变量,数据放入数组。

请注意,建议使用eval来设置具有普通变量内容的位置参数非常危险。

因为,在命令行上将变量的内容暴露于引号删除和单词拆分的过程中,无法防止变量字符串中的shell metachar引起破坏。

例如,假设在下面的示例中,是否将单词“ 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

你有没有尝试过:

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数组进行某些操作,但是随后我将不得不编写代码来加载数组,这很痛苦。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM