更新:

更新:

当我在 shell 中运行以下命令时,我会rsync在文件传输时实时看到输出:

rsync --out-format="%n" --info=name1,del2 -rt /foo bar | sed '\@/mmc/@d' | grcat /usr/share/grc/conf.rsync

但是当我在 中有相同的命令时Makefile,它似乎缓冲输出,并且只在最后吐出所有内容。我什至添加了-used确保sed未缓冲。我还添加了.ONESHELL:以防万一有什么不同:

.ONESHELL:

@rsync --out-format="%n" --info=name1,del2 -rt /foo bar | sed -u '\@/mmc/@d' | grcat /usr/share/grc/conf.rsync

但仍然rsync无法Makefile实时打印传输的文件。

是什么原因造成的?

更新:

添加--outbuf=Nrsync不会改变任何东西。

在我看来,make它正在不遗余力地主动缓冲我正在运行的任何命令Makefile

我怎样才能阻止这种行为?

答案1

问题似乎不在于 with ,rsync而是在于sed,它(相当合理地)在任何机会进行缓冲。

这是我的测试Makefile

rm:
    rm -rf /tmp/etc.test

test1: rm
    rsync -av --bwlimit=50 /etc/ localhost:/tmp/etc.test | nl -p -ba

test2: rm
    rsync -av --bwlimit=50 /etc/ localhost:/tmp/etc.test 2>&1 | sed 's!^!RSYNC>  !g' | nl -p -ba

test3: rm
    rsync -av --bwlimit=50 /etc/ localhost:/tmp/etc.test 2>&1 | sed -u 's!^!RSYNC>  !g' | nl -p -ba

make test1得到了实时显示的信息。我make test2得到缓冲输出。然而,make test3我看到交错的输出(不像缓冲那样,test2但不像那样平滑test1)。根据经验,解决方案是欺骗sed(而不是rsync)相信其输出不被缓冲:

stdbuf -oL sed …

延伸Makefile,

test4: rm
    rsync -av --bwlimit=50 /etc/ localhost:/tmp/etc.test 2>&1 | stdbuf -oL sed 's!^!RSYNC>  !g' | nl -p -ba

并进行测试,make test4我看到立即输出很像test1.我无法解释为什么test3(using sed -u) 与此解决方案不同,但确实如此。至少在我基于 Pi 的测试平台上是这样。

答案2

您可以尝试运行以下命令:

stdbuf -i0 -o0 -e make .....

或与unbuffer

unbuffer make ...

相关内容