巴什引述阵列扩展 [英] Bash quoted array expansion

查看:126
本文介绍了巴什引述阵列扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我写一个bash程序我通常构建调用,例如如下:

 宣布-a mycmd =(command.extARG1空间ARG2物等)$ {mycmd [@]}||回声失败:富

其中,死富是一个bash函数,版画错误富并退出。

但是,如果我要明确有关错误的原因,我想打印失败的命令:

 $ {mycmd [@]}||回声失败:富:$ {mycmd [*]}

因此​​,用户可以运行死命令,并找出的为什么的。然而,引用丢失在这一关 - 已空格或转义字符不会在可裁剪正和粘贴的方式打印失败的消息参数运行

有没有人有一个建议一个紧凑的方式来解决这个问题?


我认为这个问题是与参数解析为命令bash的方式交易的,和路(内置)回声处理参数。说明该问题的另一种方法是:

我怎么能打印的参数周围引号用空格在下面的bash的例子(必须作为运行的脚本,而不是在即时模式):

 #!/斌/庆典
MKDIR qatest; CD qatest
声明-a myargs =(1 23 4)
触摸$ {myargs [@]}
LS
回声$ {myargs [@]}

实际结果是:

  1 2 3 4
1 2 3 4

期望的结果。

  1 2 3 4
1 23 4

  1 2 3 4
1,2,3 4

在一些额外的bash code字符。


问题已关闭:@camh回答了辉煌:

更新脚本:

 #!/斌/庆典
MKDIR qatest; CD qatest
声明-a myargs =(1 23 4)
触摸$ {myargs [@]}
LS
回声$ {myargs [@]}
回声$(printf的'%s'的$ {myargs [@]})

输出:

  1 2 3 4
1 2 3 4
'1''2''3 4'


解决方案

您的问题是与回声。它越来越参数的正确数目,用包含空格的一些参数,但它的输出参数失去内的参数和空间之间的空间的区别。

相反,你可以使用的printf(1)输出参数始终包括报价,使得用printf的特点是连续应用格式字符串的时候有参数多于格式说明符的参数格式字符串:

 回声失败:富:$(printf的'%s'的$ {mycmd [@]})

这将会把单引号周围的每个参数,即使不需要它:

 失败:富:command.ext'空间'ARG1'ARG2'东西''等'

我用单引号,以确保其他shell元字符不处理不当。这将为除单引号本身的所有字符的工作 - 即如果有包含一个单引号的参数,从上面的命令的输出将不会削减和正确粘贴。这可能是你会得到没有得到凌乱最接近的一次。

WHen I write a bash program I typically construct calls like follows:

declare -a mycmd=( command.ext "arg1 with space" arg2 thing etc )

"${mycmd[@]}" || echo "Failed: foo"

Where die foo is a bash function that prints Error foo and exits.

But if I want to be clear about the error reason, I want to print the failed command:

"${mycmd[@]}" || echo "Failed: foo: ${mycmd[*]}"

So the user can run the dead command and find out why. However, quoting is lost on this pass - the Failed message arguments that have spaces or escaped characters are not printed in a way that can be cut-n-pasted and run.

Does anyone have a suggestion for a compact way to fix this problem?


I think the problem is the way bash deals with argument parsing for commands, and the way (builtin) echo handles arguments. Another way of stating the problem is:

How can I print the quotes around arguments with spaces in the following bash example (which must be run as a script, not in immediate mode):

#!/bin/bash
mkdir qatest; cd qatest
declare -a myargs=(1 2 "3 4")
touch "${myargs[@]}"
ls
echo "${myargs[@]}"

actual result:

1  2  3 4
1 2 3 4

desired result

1  2  3 4
1 2 "3 4"

OR

1  2  3 4
"1" "2" "3 4"

In few additional bash code characters.


Question closed: @camh answered it magnificently:

updated script:

#!/bin/bash
mkdir qatest; cd qatest
declare -a myargs=(1 2 "3 4")
touch "${myargs[@]}"
ls
echo "${myargs[@]}"
echo $(printf "'%s' " "${myargs[@]}")

output:

1  2  3 4
1 2 3 4
'1' '2' '3 4'

解决方案

Your problem is with echo. It is getting the correct number of parameters, with some parameters containing spaces, but it's output loses the distinction of spaces between parameters and spaces within parameters.

Instead, you can use printf(1) to output the parameters and always include quotes, making use of printf's feature that applies the format string successively to parameters when there are more parameters than format specifiers in the format string:

echo "Failed: foo:" $(printf "'%s' " "${mycmd[@]}")

That will put single quotes around each argument, even if it is not needed:

Failed: foo: 'command.ext' 'arg1 with space' 'arg2' 'thing' 'etc'

I've used single quotes to ensure that other shell metacharacters are not mishandled. This will work for all characters except single quote itself - i.e. if you have a parameter containing a single quote, the output from the above command will not cut and paste correctly. This is likely the closest you will get without getting messy.

这篇关于巴什引述阵列扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆