在 cloud-init 过程中显示 scp 的进度
Posted
技术标签:
【中文标题】在 cloud-init 过程中显示 scp 的进度【英文标题】:Showing progress of scp during cloud-init process 【发布时间】: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,请参阅***.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。不同的问题,相同的答案。
【参考方案1】:
像其他一些工具一样,scp
检查其输出是否发送到 TTY(通过使用 isatty
),如果不是则禁用进度表输出(您可以找到类似的情况,例如 ls --color=auto
发出仅当输出到终端时才使用颜色代码)。
您可以通过在script
(如in this answer 所示)或任何其他运行程序并将其输出连接到PTY。
【讨论】:
谢谢!作为奖励点,您能解释一下为什么在script -qfc "$(printf "%q " "$@")" /dev/null
中的%q
之后需要一个空格吗?
没有空格参数会粘在一起,因为bash
printf
重用所有参数的格式。
啊,好的,我知道它在做什么了。最后一个参数的末尾有一个空格,但我想这无关紧要。以上是关于在 cloud-init 过程中显示 scp 的进度的主要内容,如果未能解决你的问题,请参考以下文章