鱼脚本中的嵌套代码块和子外壳

时间:2018-07-26 23:45:55

标签: bash fish

我正在努力将一个bash script转换为鱼。我已经完成了大部分操作,但是有一个复杂的片段,其中包含多个嵌套和链接的块。

在bash中考虑以下简化的部分。不必过多地阅读逻辑或命令,只需遵循结构并注意()中两个重定向到comm的子shell。

dummy () {
    {
    comm -13 \
        <(cat $CACHEDLIST | gawk  '{print $1}' FS='\t' OFS='\t') \
        <(cat $PDFLIST | gawk '{print $1}' FS='\t' OFS='\t') \
    } | fzf
}

我将所有{}块都转换为begin; end。然后有两个子shell块重定向到comm -13,我也将其转换为begin; end鱼块,并将整个块通过管道传递到fzf。因此,最终结果非常简单:

function dummy
    begin
        comm -13 \
             <begin; echo "Arg1"; end \
             <begin; echo "Arg2"; end \
    end | fzf
end

如果我在外壳中运行这个小块,我会得到:

(line 7): 'end' outside of a block

为什么?我唯一的猜测是,不希望继续使用行,因为肯定有两个<begin; ...; end \行。

2 个答案:

答案 0 :(得分:3)

一种翻译方法是使用显式命名管道代替bash的过程替换构造。请注意,comm周围的花括号不是必需的,因为命令组中只有一个命令。在fish函数中,这意味着一对更少的开始-结束对。

function dummy
    begin
        mkfifo p1 p2
        gawk '{print $1}' FS='\t' OFS='\t' "$CACHEDLIST" > p1 &
        gawk '{print $1}' FS='\t' OFS='\t' "$PDFLIST" > p2 &
        comm -13 p1 p2 | fzf
        rm p1 p2
    end

(您可能希望通过在临时目录中创建p1p2并确保在发生任何错误时将其删除来使其更加健壮。)

答案 1 :(得分:2)

看来您已经解决了问题,但为了后代:

function dummy 
    comm -13 (cut -f1 $CACHEDLIST | psub) (cut -f1 $PDFLIST | psub) | fzf
end