【发布时间】:2012-10-10 17:06:56
【问题描述】:
当我编写一个 bash 程序时,我通常会构造如下调用:
declare -a mycmd=( command.ext "arg1 with space" arg2 thing etc )
"${mycmd[@]}" || echo "Failed: foo"
其中die foo 是一个bash 函数,它打印Error foo 并退出。
但是如果我想清楚错误原因,我想打印失败的命令:
"${mycmd[@]}" || echo "Failed: foo: ${mycmd[*]}"
所以用户可以运行 dead 命令并找出为什么。但是,在此过程中引用丢失了 - 包含空格或转义字符的 Failed 消息参数不会以可以剪切-n-粘贴和运行的方式打印。
有没有人建议用一种紧凑的方法来解决这个问题?
我认为问题在于 bash 处理命令参数解析的方式,以及(内置)echo 处理参数的方式。说明问题的另一种方式是:
我如何打印以下 bash 示例中带空格的参数的引号(必须作为脚本运行,而不是立即模式):
#!/bin/bash
mkdir qatest; cd qatest
declare -a myargs=(1 2 "3 4")
touch "${myargs[@]}"
ls
echo "${myargs[@]}"
实际结果:
1 2 3 4
1 2 3 4
想要的结果
1 2 3 4
1 2 "3 4"
或
1 2 3 4
"1" "2" "3 4"
在几个额外的 bash 代码字符中。
问题已结束:@camh 精彩回答:
更新脚本:
#!/bin/bash
mkdir qatest; cd qatest
declare -a myargs=(1 2 "3 4")
touch "${myargs[@]}"
ls
echo "${myargs[@]}"
echo $(printf "'%s' " "${myargs[@]}")
输出:
1 2 3 4
1 2 3 4
'1' '2' '3 4'
【问题讨论】:
-
您应该更喜欢
printf '%q'或 Bash 4.4 的"${mycmd[@]@Q}"扩展而不是printf "'%s'"。在许多情况下,像这样的幼稚引用会失败,例如myargs=(1 2 "3' 4").