【发布时间】:2022-01-11 18:32:34
【问题描述】:
当我启动一个新服务器时,我使用一个 cloud-init 脚本来自动化这个过程。我关注这个过程的进展:
$ tail -f /var/log/cloud-init-output.log
在使用 scp 获取备份文件并将其通过 tar -zx 管道传输时,我在 cloud-init 脚本中尝试了以下操作:
$ scp myuser@123.45.6.789:path/to/file.tar.gz /dev/stdout | tar -zx
虽然此命令有效,但scp 输出的方便进度指示不会出现在tail -f 输出中...即我看不到类似以下的进度:
file.tar.gz 57% 52MB 25.2MB/s 00:02
我也尝试过像这样的 bash 进程替换:
$ scp myuser@123.45.6.789:path/to/file.tar.gz >(tar -zx)
而且tail -f 输出中仍然没有出现进度指示。
如何在tail -f 输出中保留进度指示?尤其是在获取较大的备份文件时查看进度,保留这些指示会非常方便。
请注意,当我直接在 bash 脚本中运行上述两个脚本时(顶部有 set -x),“bash 进程替换”变体而不是“管道”变体的进度确实显示...但是当跟踪 cloud-init 日志,两种变体都显示进度。
看起来 cloud-init 只是将 stdout 和 stderr 从所有 cloud-init 阶段发送到 /var/log/cloud-init-output.log(请参阅 here)。
因此,我们可以通过以下调用重新创建 cloud-init 进程(出于此问题的目的):
$ scp myuser@123.45.6.789:path/to/file.tar.gz >(tar -zx) >output.log 2>&1
然后我们分别按照这个日志文件:
$ tail -f output.log
奇怪的是……这个output.log 文件中没有出现任何进度状态。然而进度状态肯定会被发送……下面唯一的变化是直接发送到/dev/stdout而不是output.log:
$ scp myuser@123.45.6.789:path/to/file.tar.gz >(tar -zx) >/dev/stdout 2>&1
file.tar.gz 57% 52MB 25.2MB/s 00:02
那么,当我们将stdout 定向到output.log 时,为什么我们会在/dev/stdout 上看到进度状态,但在output.log 上却看不到?
【问题讨论】:
-
scp如果 stdout 不是 TTY(您的文件不是),则关闭进度表。看起来你可以通过使用script(或在 PTY 下运行程序的其他东西)来说服它输出是 TTY,请参阅stackoverflow.com/a/1402389 -
天才@Hasturkun!我不知道一个命令可以像这样改变它的输出,没有一个明确的选项!仅供参考,this answer 中的辅助功能对我很有帮助,按照评论中的建议添加了
-e选项...所以我可以在正常命令前加上辅助功能:fake_tty scp myuser@123.45.6.789:path/to/file.tar.gz >(tar -zx) >output.log 2>&1,现在可以看到进度在output.log! (我认为它在实际的 cloud-init 中会起作用,但我还没有尝试过)。如果您发布答案,我会接受...谢谢! -
OK 修改...它没有
-e选项...即仅script -qfc(完全按照linked answer)...使用script -qfce的某些原因给出了No such file or directory error。 -
您可能想要使用
-qfec,因为-c需要一个参数(所以我认为将e作为一个参数)。我认为如果我将其标记为另一个的副本会更好(因为我在这里唯一的贡献是scp不会进展到非 TTY 的事实),而不是做一个链接 - 主要是答案。 -
啊,是的,您对 qfec 的命令是正确的...有效。我不确定这是否真的是重复的……这是一种新的教学,即 scp 将进度表禁用为非 TTY,即使(一旦你知道)答案与另一个相同。 IE。不同的问题,相同的答案。
标签: linux bash scp cloud-init