bash: 如何抑制来自 scp 输出的登录信息
bash: how to suppress login message from scp output
我有一个简单的bash函数供交互使用:
push-file() {
hosts=""
src=""
dest=""
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
写入标准错误。这将需要通过管道传输到 tail -n 11
。我不能直接将 stderr 指向 /dev/null
,因为 AUP 消息之后的错误消息可能会丢失。
进度表由scp
写入标准输出,但似乎只有当标准输出是终端时才会写入。任何涉及 &>
的允许通过管道传输 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
您可以(显然)通过提高底层 ssh
连接的错误级别来抑制输出。 (归功于 https://askubuntu.com/a/703230。)
scp -o LogLevel=Error "$src" "root@$h:$dest"
我有一个简单的bash函数供交互使用:
push-file() {
hosts=""
src=""
dest=""
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
写入标准错误。这将需要通过管道传输到tail -n 11
。我不能直接将 stderr 指向/dev/null
,因为 AUP 消息之后的错误消息可能会丢失。进度表由
scp
写入标准输出,但似乎只有当标准输出是终端时才会写入。任何涉及&>
的允许通过管道传输 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
您可以(显然)通过提高底层 ssh
连接的错误级别来抑制输出。 (归功于 https://askubuntu.com/a/703230。)
scp -o LogLevel=Error "$src" "root@$h:$dest"