如何将一个脚本的多个输出传递到另一个脚本

时间:2015-07-31 09:45:30

标签: shell zsh

我有一个zsh函数,它将给定参数列表分成两行,用空格分隔:

function foo() {
    echo "a b c";
    echo "d e f";
}

$foo
a b c 
d e f

我想将输出传递给另一个函数,以便它识别为两个参数。

function bar() {
    for i in "$@"
    do
        echo $i;
    done
}

现在它的工作原理为:

$ bar $(foo)
a
b
c
...

我想拥有什么

$ bar $(foo)
a b c
d e f

我试图在“引号”和“'双引号'”中回显结果行,但这没有结果。

(zsh 5.0.5(x86_64-apple-darwin14.0))

更新:使用bar "$(foo)"语法,现在它似乎只是一个参数:

function bar() {
    echo "\$1=";
    echo $1;
    echo "\$2=";
    echo $2;
}

$ bar "$(foo)"
$1=
a b c
d e f
$2=

1 个答案:

答案 0 :(得分:1)

您可以使用某些zsh的发烧友参数扩展功能将foo的输出拆分为单独的字词。

foo () {
    echo "a b c"
    echo "d e f"
}

bar () {

    printf "Arg: %s\n" "$@"
}

bar "${(f):-$(foo)}"

发生了什么:

  1. $(foo)计算包含嵌入换行符的单个字符串。 (警告:任何尾随换行都将被丢弃;但这不应该是一个问题。)
  2. ${:-whatever}扩展为:-后面的字符串。它本质上是默认值扩展,但您省略了要展开的参数的名称,因此始终扩展为默认值。它似乎毫无意义,但它允许我们将参数扩展标志应用于任意文本(例如步骤1中的命令替换)。
  3. ${(f)...}将字符串拆分为换行符上的多个单词。
  4. 一起,单一扩展的行为类似于:

    lines=()
    while read line; do
        lines+=( $line )
    done < <(foo)
    
    bar $lines[@]
    

    或者,将bar定义为

    bar () {
        printf "Arg: %s\n" "${(f)1}"
    }
    

    使用

    获得相同的结果
    bar "$(foo)"
    

    (报价至少仍然是必要的)。