I have a simple bash function for interactive use:
push-file() {
hosts="$1"
src="$2"
dest="$3"
for h in "$hosts"
do
echo "=== $h ==="
scp "$src" root@$h:"$dest"
done
}
I can then type, for example:
push-file "host1 host2" testfile /tmp/
to copy testfile
to both of the hosts. (In reality in place of the "host1 host2"
I might use a variable e.g. "$foo_hosts"
to specify a certain group of hosts.)
However, there is a complication: on each of the hosts, there are 10 lines of boilerplate AUP message displayed whenever you ssh to them, so the output looks like:
=== 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
But I want it to look like:
=== host1 ===
testfile 100% 188 11.2KB/s 00:00
=== host2 ===
testfile 100% 188 11.6KB/s 00:00
(Here, the final line from scp
is a progress meter -- you are seeing it here as it appears on the terminal after completion of the transfer.)
Now, the AUP message is always 10 lines long, so it should just be a case of removing the first 10 lines, but there are further complicating factors:
The AUP message is written by scp
to stderr. This will need to be piped to the tail -n 11
. I cannot afford to just direct stderr to /dev/null
, as error messages after the AUP message may be lost.
The progress meter is written to stdout by scp
, but it seemingly is only written if stdout is a terminal. Any tricks involving &>
which allow stderr to be piped also seem to cause the stdout of the scp
process to be a pipe rather than a terminal, and then the progress meter is suppressed.
The best I could come up with was to replace:
scp "$src" root@$h:"$dest"
with:
{ 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
which works, but is hideous.
QUESTION - Is there anything simpler and cleaner?
Here's the OpenSSH version, in case there is a way to modify the scp behaviour directly rather than postprocessing the output in bash: OpenSSH_7.6p1 Ubuntu-4ubuntu0.3, OpenSSL 1.0.2n 7 Dec 2017
You can (apparently) suppress the output by raising the error level of the underlying ssh
connection. (Credit to https://askubuntu.com/a/703230.)
scp -o LogLevel=Error "$src" "root@$h:$dest"