当我在 shell 中运行以下命令时,我会rsync
在文件传输时实时看到输出:
rsync --out-format="%n" --info=name1,del2 -rt /foo bar | sed '\@/mmc/@d' | grcat /usr/share/grc/conf.rsync
但是当我在 中有相同的命令时Makefile
,它似乎缓冲输出,并且只在最后吐出所有内容。我什至添加了-u
以sed
确保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=N
也rsync
不会改变任何东西。
在我看来,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 ...