Я намерен передать полные и инкрементные резервные копии моих подобъемов btrfs в службу архивации на магнитную ленту. Служба предоставляет конечные точки FTP и SSH. Если бы мне было разрешено выполнять произвольные команды на конечной точке SSH, я бы сделал следующее для инкрементного резервного копирования:
btrfs send -p $LAST_SUBVOLUME $NEXT_SUBVOLUME | compress | encrypt |
ssh -p $PORT $USER@$ENDPOINT "cat > $SUBVOLUME.$YYYYMMDD.btrfs.bz2.gpg"
Мне, однако, не разрешено делать это:
$ ssh -p $PORT $USER@$ENDPOINT
Last login: Mon Jan 3 01:23:45 2067 from 123.456.789.123
This account is restricted by rssh.
Allowed commands: scp sftp rsync
If you believe this is in error, please contact your system administrator.
Connection to some.remote.endpoint closed.
Так что вместо этого я решил использовать протокол SCP для передачи. Однако мой двоичный файл scp
отказывается передавать именованный канал:
$ scp -P $PORT <(btrfs send -p $LAST_SUBVOLUME $NEXT_SUBVOLUME | compress | encrypt) \
$USER@$ENDPOINT:$SUBVOLUME.$YYYYMMDD.btrfs.bz2.gpg
/dev/fd/63: not a regular file
Ирония в том, что, очевидно, РЕДАКТИРОВАТЬ (2017-06-03): Это было неправильное наблюдение. Как отмечает Кенстер, протокол SCP не позволяет отправлять файлы неизвестного размера.scp
когда-то делал правильные вещи. Полагаю, не все думали, что передача именованных каналов может быть вменяемой / полезной.
ОБНОВЛЕНИЕ (2017-06-04): Я также попытался передать данные, используя протокол SFTP. По-видимому, протокол FTP позволяет отправлять файлы неизвестного размера, о чем свидетельствует поддержка передачи данных в двоичные файлы ftp
(ссылка) и ncftpput
(ссылка, описание раздела, последний абзац). Я не нашел такой поддержки в SFTP-клиентах, которые я пробовал (sftp
, lftp
), что может указывать на то, что SFTP (в отличие от FTP) не поддерживает отправку файлов неизвестного размера (в отличие от того, что я думал, SFTP не просто FTP-туннельный) через SSH; это другой протокол).
ОБНОВЛЕНИЕ (2017-06-05): Согласно интернет-проекту протокола SFTP версии 3 (ссылка), каждый пакет уровня приложения должен указывать длину полезной нагрузки перед полезной нагрузкой (ссылка, раздел 3). Однако SFTP поддерживает поиск в записанном файле (ссылка, раздел 6.4) с явной поддержкой записи за пределы текущего конца файла. Поэтому, если это возможно, можно использовать небольшой буфер на стороне клиента и отправлять файл неизвестного размера небольшими порциями известного размера:
#!/bin/bash
# <Exchange SSH_FXP_INIT requests.>
# <Send an SSH_FXP_OPEN request.>
CHUNK_SIZE=32768
OFFSET=0
IFS=''; while read -r -N $CHUNK_SIZE CHUNK; do
ACTUAL_SIZE=`cat <<<"$CHUNK" | head -c -1 | wc -c`
# <Send an SSH_FXP_WRITE request with payload $CHUNK of size
# $ACTUAL_SIZE at offset $OFFSET.>
OFFSET=$(($OFFSET+$ACTUAL_SIZE))
done < <(command)
# <Send an SSH_FXP_CLOSE request.>
Однако выполнение связи вручную через оболочку было бы довольно болезненным. Я ищу клиента SFTP, который предоставляет такую функциональность.