English 中文(简体)
Bash变量中未得到尊重
原标题:Quoting not respected inside a bash variable
  • 时间:2009-09-04 06:37:19
  •  标签:

我把论点存放在一个变数中。 我最后想要的是:

mock -r myconfig --define "debug_package %{nil}" --resultdir results --rebuild mypackage.src.rpm

我在此试图:

set -x    # for debugging

RESULTDIR=results
MOCK_CONFIG="myconfig"
MOCK_ARGS="-r $MOCK_CONFIG --define "debug_package %{nil}" --resultdir $RESULTDIR"
cmd="mock $MOCK_ARGS --rebuild mypackage.src.rpm"
$cmd

结果是:

+ RESULTDIR=results
+ MOCK_CONFIG=myconfig
+ MOCK_ARGS= -r myconfig --define "debug_package %{nil}" --resultdir results 
+ cmd= mock -r myconfig --define "debug_package %{nil}" --resultdir results --rebuild mypackage.src.rpm 
+ mock -r myconfig --define  "debug_package   %{nil}"  --resultdir results --rebuild mypackage.src.rpm
ERROR: Bad option for  --define  ("debug_package).  Use --define  macro expr 

如你所知,对<代码>-define参数的争论没有被适当引用。 <0>------>-------------------------> 思想 I m 仅通过debug_ Pack%,但不完整。

我在界定<代码>MOCK_ARGS时尝试了各种报价,甚至试图从<代码>debug_ Pack和%{nil}之间找到空间。

引用和(或)越狱使我能够制定这一论点清单,并从这一文字中执行指挥?

EDIT:

造成指挥变数的I m原因在于它最终变成了某种伐木功能,然后执行指挥。

另外,我也来过,这意味着我应当使用阵列而不是变数。 我开始试验阵列,但迄今为止还没有找到解决办法。

最佳回答

游艇就是这样做的路途。 这里我要谈谈:

log_and_run() {
    echo "$(date): running command: $*"
    "$@"
    echo "$1 completed with status $?"
}

RESULTDIR=results
MOCK_CONFIG="myconfig"
MOCK_ARGS=(-r "$MOCK_CONFIG" --define "debug_package %{nil}" --resultdir "$RESULTDIR")
cmd=(mock "${MOCK_ARGS[@]}" --rebuild mypackage.src.rpm)
log_and_run "${cmd[@]}"
# could also use: log_and_run mock "${MOCK_ARGS[@]}" --rebuild mypackage.src.rpm

请注意,* 美元扩大到按空间分类的所有参数(适于通过记录指挥);而“$@”则扩展至所有参数,作为单独的词语(如在标识_和_run中使用的,第一个参数将作为执行指挥处理,其余部分作为参数);同样,“{MOCK_ARGS[@]}”扩展到科索沃内政部的所有组成部分。 ARGS作为单独的措辞,无论是否含有空间(因此,科索沃统计局的每个组成部分都成为一厘米的元素,没有引人混淆)。

此外,我引述了科索沃卫生部的扩大。 CONFIG和SRDIR;这里之所以需要,是因为它们没有空间,但当它们曾经控制空间时,是好的习惯(例如,它是否从外部传入你的文字?) 然后,你可以认为它可能包含空间。

BTW,如果你需要通过额外参数来履行这一职能(如果你使用档案名称的示例来记录),那么,你可以使用-array slicing,只将后来的参数分开,用于记录/execute:

log_and_run() {
    echo "$(date): running command ${*:2}" >>"$1" 
    "${@:2}"
    echo "$2 completed with status $?" >>"$1"
}
#...
log_and_run test.log "${cmd[@]}"

增编:如果你想在标识中引用含有空间的参数,你可以“非常”地构造标识,并做你想要的引述。 例如:

log_and_run() {
    local log_cmd=""
    for arg in "$@"; do
        if [[ "$arg" == *" "* || -z "$arg" ]]; then
            log_cmd="$log_cmd "$arg""
        else
            log_cmd="$log_cmd $arg"
        fi
    done
    echo "$(date): running command:$log_cmd"
    ...

请注意,这将处理参数和空白参数的空间,但不(例如)参数内的双重引用。 这种“权利”可能会被任意混淆......

此外,我建造“日志”探测仪的方式与一个主要空间站在一起;我处理上述问题,将空间排出回“指挥”。 如果您需要实际对空间进行分类,则使用<代码>> ${log_cmd# }"。

问题回答

壳牌照可能是错误的。 在许多情况下,cmd=“blah$blah”;$cmdblah$blah不同。 您可尝试<条码>,而不是按美元计算。

2. 要求使用这种手法,而不是模拟:

#!/usr/bin/perl
print join("
",@ARGV),"
";

你可能感到惊讶的是,论点清单实际上是什么:

-r
myconfig
--define
"debug_package
%{nil}"
--resultdir
results
--rebuild
mypackage.src.rpm

虽然我猜测“set-x”产出正试图用单一字标出。

我最近学到的一个冰trick是:

function f {
  echo "$@"
}

实际正确地将立场论点推向f ($*. .n t)。

它像“平等”一样,赋予你可能打算:

set -x    # for debugging
RESULTDIR=results
MOCK_CONFIG="myconfig"
MOCK_ARGS="-r $MOCK_CONFIG " --define "debug_package %{nil}" --resultdir  "$RESULTDIR"
cmd="mock $MOCK_ARGS --rebuild mypackage.src.rpm"
echo $cmd
eval $cmd

产出:

+ echo mock -r myconfig --define  "debug_package   %{nil}"  --resultdir results --rebuild mypackage.src.rpm
mock -r myconfig --define "debug_package %{nil}" --resultdir results --rebuild mypackage.src.rpm
+ eval mock -r myconfig --define  "debug_package   %{nil}"  --resultdir results --rebuild mypackage.src.rpm
++ mock -r myconfig --define  debug_package %{nil}  --resultdir results --rebuild mypackage.src.rpm
-r
myconfig
--define
debug_package %{nil}
--resultdir
results
--rebuild
mypackage.src.rpm




相关问题
热门标签