【问题标题】:Get the executed command, quoted params, after executing `"${argv[@]}"`执行`"${argv[@]}"`后获取执行的命令,引用的参数
【发布时间】:2012-08-11 19:06:43
【问题描述】:

此功能有效:

source foo.bash && foo -n "a b c.txt"

问题是,无论我尝试了什么,我都无法让最后一行 echo "$CMD"(或 echo $CMD)准确地生成此输出:

cat -n "a b c.txt"

如何实现?

# foo.bash
function foo() {
    local argv=("$@");
    local OUT=`cat "${argv[@]}"`
    local CMD=`echo cat "${argv[@]}"`
    echo "--------------------------"
    echo "$OUT"
    echo "--------------------------"
    echo "$CMD"
}

输出是:

cat -n a b c.txt

使用此命令:foo -n \"a b c.txt\" 它确实可以显示命令,但通过反引号执行时会出错。

文件"a b c.txt" 是一个有效的小文本文件。

【问题讨论】:

  • 我提供了一个答案,但我希望你不打算用那个输出调用 eval。
  • 我不确定这是否可能,当您说foo -n "a b c.txt" bash 将参数视为-na b c.txt 删除引号并保留空格时。对于foo -n \"a b c.txt\",参数为-n"abc.txt"。我不确定你是否可以做你想做的事情,即让 bash 保留引号,而默认行为恰好是剥离。也许IFS魔法......或者别的什么。没有什么我能马上想到的
  • @another.anon.coward 是的,但它确实适用于local OUT=`cat "${argv[@]}"`,如果不可能,它也不应该适用于那个。对吗?
  • 对不起,我不太明白。 OUT 将包含cat -n a b c.txt 的输出,其中a b c.txt 是有效文件,否则它将不包含任何内容,因为丢失的文件将显示在stderr 上,而不会保存在OUT 中。
  • 只是为了澄清文件名包含"s?

标签: linux bash shell


【解决方案1】:

您需要在作业中转义引号:

local CMD="cat \"${argv[@]}\""

另外,连接字符串不需要 echo。

【讨论】:

  • 这给出了cat "-n a b c.txt",这也不是我所期望的。请注意,提供的代码只是一个 PoC,可能有任何标志(命令实际上是 git)。我希望与键入的内容完全相同:cat -n "a b c.txt".
  • @Flavius - 引号实际上从未传递给被调用的函数。
【解决方案2】:

好了,在number of tokens in bash variable 的帮助下,我想出了正确的解决方案。

我几乎忘记了为什么我们实际上需要为一个参数引用,因为它有多个单词!

function foo() {
    local argv=( "$@" );
    local OUT=`cat "${argv[@]}"`
    echo "--------------------------"
    echo "$OUT"
    echo "--------------------------"
    local CMD="cat"
    for word in "${argv[@]}"; do
        words="${word//[^\ ]} "
        if [[ ${#words} > 1 ]]; then
            local CMD="$CMD \"${word}\""
        else
            local CMD="$CMD $word"
        fi
    done
    echo "$CMD"
}

希望它对某人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多