我有一个简单的bash函数可供交互使用:
push-file() {
hosts="$1"
src="$2"
dest="$3"
for h in "$hosts"
do
echo "=== $h ==="
scp "$src" root@$h:"$dest"
done
}
然后我可以输入,例如:
push-file "host1 host2" testfile /tmp/
将testfile
复制到两个主机。 (实际上,我可以使用变量"host1 host2"
来代替"$foo_hosts"
来指定一组主机。)
但是,这很复杂:在每台主机上,每当您对它们进行ssh时,都会显示10行样板AUP消息,因此输出如下:
=== host1 ===
Access to this system is monitored [etc...]
[9 more lines of AUP]
testfile 100% 188 11.2KB/s 00:00
=== host2 ===
Access to this system is monitored [etc...]
[9 more lines of AUP]
testfile 100% 188 11.6KB/s 00:00
但是我希望它看起来像:
=== host1 ===
testfile 100% 188 11.2KB/s 00:00
=== host2 ===
testfile 100% 188 11.6KB/s 00:00
(这里,scp
的最后一行是进度表-您在传输完成后会在终端上看到它。)
现在,AUP消息的长度始终为10行,因此仅是删除前10行的情况,但是还有其他复杂因素:
AUP消息由scp
写入stderr。这将需要通过管道传递到tail -n 11
。我不能仅仅将stderr定向到/dev/null
,因为AUP消息之后的错误消息可能会丢失。
进度表由scp
写入stdout,但似乎仅在stdout是终端时才写入。任何涉及&>
的技巧都可以通过stderr进行管道传输,似乎也导致scp
进程的标准输出是管道而不是终端,从而抑制了进度表。
我想出的最好办法是更换:
scp "$src" root@$h:"$dest"
具有:
{ script -q -c "scp \"$src\" root@$h:\"$dest\" 3>&1 1>&2 2>&3" /dev/null | tail -n +11; } 3>&1 1>&2 2>&3
有效,但很可怕。
问题-有没有更简单,更简洁的方法?
这是OpenSSH版本,以防万一有一种方法可以直接修改scp行为,而不是对bash中的输出进行后处理:OpenSSH_7.6p1 Ubuntu-4ubuntu0.3, OpenSSL 1.0.2n 7 Dec 2017
答案 0 :(得分:1)
您可以(显然)通过提高基础ssh
连接的错误级别来抑制输出。 (贷记为https://askubuntu.com/a/703230。)
scp -o LogLevel=Error "$src" "root@$h:$dest"