
Я просто хотел создать 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