Сохранение вывода команды на ресурсе SFTP

Сохранение вывода команды на ресурсе SFTP

Я просто хотел создать tar-шар и хранить его только на ресурсе SFTP. Поскольку я параноидально отношусь к повреждению данных, я обычно храню sha256sums моих tar-шаров вместе с ними, если это то, на что я хочу положиться, и вычисляю их как при создании архивов, так и после их записи, считывая их с носителя, на котором они хранятся.

Я предположил, что это довольно просто, поэтому ввел следующую команду:

tar --exclude='./somefolder' -zc . | tee "sftp://mydomain.ending/storage/location/on/server/sth.tar" | sha256sum

Я также попробовал то, что Nautilus использует для своих удаленных терминалов:

tar --exclude='./somefolder' -zc . | tee ":/run/user/1000/gvfs/sftp:host=mydomain.ending/storage/location/on/server/sth.tar" | sha256sum

Однако результаты были следующими:

tee: 'sftp://mydomain.ending/storage/location/on/server/sth.tar': No such file or directory

и

tee: ':/run/user/1000/gvfs/sftp:host=mydomain.ending/storage/location/on/server/sth.tar': No such file or directory

соответственно.

Как мне сохранить tar-шар там, не сохраняя его локально? Желательно без предварительного монтирования удаленного ресурса в какую-то папку, чтобы его можно было легко использовать.

Я использую Ubuntu 16.04 (с Linux 4.4.0).

решение1

Без модных монтирований gvfs или sshfs вам нужно использовать клиент sftp. Я выбираю lftp>=4.7, потому что он работает с каналами FIFO ( scpи sftpне работает).

Это работает bashв Linux:

tar --exclude='./somefolder' -zc . \
 | tee >(lftp -c 'connect sftp://user:pass@server/path/ ;put /dev/stdin -o sth.tar.gz;') \
 | sha256sum

Альтернативный вариант использования sshклиента (внешние скобки необходимы для интерактивной аутентификации по паролю):

(tar --exclude='./somefolder' -zc . \
 | tee >(ssh user@server "cat > /path/sth.tar.gz") \
 | sha256sum)

Обратите внимание, tee'sаргумент выглядит немного экзотично, но это непереносимая bashмагия, позволяющая избежать дополнительных mkfifoкоманд, описанная в man bash:

Процесс замены

Подстановка процессов поддерживается в системах, которые поддерживают именованные каналы (FIFO) или метод именования открытых файлов /dev/fd. Он принимает форму <(list) или >(list). Список процессов запускается с его входом или выходом, подключенным к FIFO или некоторому файлу в /dev/fd. Имя этого файла передается в качестве аргумента текущей команде в результате расширения. Если используется форма >(list), запись в файл предоставит входные данные для списка. Если используется форма <(list), файл, переданный в качестве аргумента, должен быть прочитан для получения выходных данных списка.

решение2

Nautilus использует gvfsдля монтирования удаленных хранилищ, таких как сервер SFTP в вашем вопросе. Это позволяет вам обращаться с удаленным сервером так, как будто он является частью вашей локальной файловой системы. Путь, по которому он монтируется, обычно

/run/user/<your uid>/gvfs/<server specification>/<path>

Я почти уверен, что префикс всегда

/run/user/<your uid>

поэтому вы можете найти эту точку монтирования, выполнив команду lsили Tabпройдя по этому каталогу.

Найдя эту точку монтирования, вы можете использовать ее teeкак обычно (добавив переносы строк для ясности):

tar --exclude='./somefolder' -zc .  \
| tee "/run/user/1000/gvfs/sftp:host=mydomain.ending/storage/location/on/server/sth.tar"  \
| sha256sum

В качестве альтернативы можно избежать монтирования GVFS и при этом избежать непереносимой подмены процесса, используя SSH вместо SFTP:

tar --exclude='./somefolder' -zc .  \
| ssh mydomain.ending 'tee "/storage/location/on/server/sth.tar"' 2>/dev/null  \
| sha256sum

К сожалению, sftpпрограмма не позволяет отправлять файлы на удаленный хост через одну командную строку, а только извлекать их.

Как отмечает @rudimeier, указанный выше sshметод загружаети загрузкифайл, чтобы избежать его локального хранения. Если вы не хотите повторно загружать его, может быть лучше сделать это sha256sumудаленно:

tar --exclude='./somefolder' -zc .  \
| ssh mydomain.ending 'tee "/storage/location/on/server/sth.tar" | sha256sum' 2>/dev/null

Связанный контент