Вот альтернативное решение:
Во всех приведенных выше примерах, предлагающих ssh + cat, предполагается, что "cat" доступна в системе назначения.
В моем случае система (резервное копирование Hetzner) имела очень ограниченный набор инструментов, предлагающих sftp, но не полную оболочку. Таким образом, использование ssh + cat было невозможно. Я придумал решение, которое использует недокументированный флаг "scp -t". Полный сценарий может быть найден ниже.
#!/bin/bash
function join_e
{
for word in $*; do
echo -n "--exclude=$word "
done
}
CDATE=`date +%Y%m%d%H%M%S`
# Make password available to all programs that are started by this shell.
export OPASS=YourSecretPasswrodForOpenSslEncryption
#-----------------------------------------------
# Directory and file inclusion list
ILIST=(
var/lib
)
# Directory and file exclusion list
ELIST=(
var/lib/postgresql
)
# 1. tar: combine all files into a single tar archive
# a. Store files and directories in ILIST only.
# b. Exclude files and directories from ELIST.
# 2. xz: compress as much as you can utilizing 8 threads (-T8)
# 3. openssl: encrypt contents using a password stored in OPASS local environment variable
# 4. cat: concatenate stream with SCP control message, which has to be sent before data
# a. C0600 - create a file with 600 permissions
# b. 107374182400 - maximum file size
# Must be higher or equal to the actual file size.
# Since we are dealing with STDIN, we have to make an educated guess.
# I've set this value to 100x times my backups are.
# c. stdin - dummy filename (unused)
# 5. ssh: connect to the server
# a. call SCP in stdin (-t) mode.
# b. specify destination filename
nice -n 19 bash -c \
"\
tar $(join_e ${ELIST[@]}) -cpf - -C / ${ILIST[*]} \
| xz -c9e -T8 \
| openssl enc -aes-256-cbc -pass env:OPASS \
| cat <(echo 'C0600 107374182400 stdin') - \
| ssh username@server.your-backup.de "\'"scp -t backup-${CDATE}.tar.xz.enc"\'"\
"
Обновление 2019.05.08:
Согласно запросу, ниже приведена гораздо более простая и короткая версия.
#!/bin/sh
# WORKS ON LARGE FILES ONLY
cat filename.ext \
| cat <(echo 'C0600 107374182400 stdin') - \
| ssh user@host.dom 'scp -t filename.ext'