【问题标题】:How to pass several outputs of one script into another script如何将一个脚本的多个输出传递到另一个脚本
【发布时间】:2015-07-31 09:45:29
【问题描述】:

我有一个 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=

【问题讨论】:

    标签: shell zsh


    【解决方案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)...} 将字符串拆分为换行符上的多个单词。

    单个扩展的作用类似于:

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

    或者,将bar 定义为

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

    得到同样的结果

    bar "$(foo)"
    

    (至少,引号仍然是必要的)。

    【讨论】:

    • 太好了,谢谢你的解释。读了几遍才明白))我明天可以试试。我是否正确理解这种语法允许我从任何字符串(如xargs)中创建一个参数数组?说,我有$paths="path1 path2 "path 3"。所以"${(f):-$paths}" 分成三行,对吧?”
    • 不引用。 paths=$'path1\npath2\npath 3' 就是这样。正如您所写,拆分会更加困难,因为嵌入的引号只是字符串中的文字字符,而不是“嵌套”以提供结构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    相关资源
    最近更新 更多