Як скопіювати файл, який все ще записується через ssh?


20

Ось така ситуація:

  1. Я завантажую великий файл з клієнта A на сервер за допомогою sftp.
  2. Мені також потрібно завантажити цей файл з сервера на клієнт B через ssh.

Що я хотів би зробити, це запустити передачу з сервера на клієнт B, коли завантаження все ще відбувається від клієнта А.

Який найкращий метод / інструмент для цього?

ОНОВЛЕННЯ :

Поки що відповіді цікаві - я обов’язково їх прочитаю та перевіряю. Бонусні бали за відповіді, які не залежать від контролю над тим, як Клієнт А завантажує файл. (тобто єдине, що ми знаємо від клієнта A, це те, що файл записується на відоме ім’я файлу.)


Ооо, добре запитання. Це, безумовно, можливо, але я не знаю нічого, що реалізує це
Майкл Мрозек

Відповіді:


10

Для одного файлу замість використання SFTP ви можете передавати файл через ssh за допомогою catабо pvна стороні, що надсилає, і teeна середньому сервері обидва надсилати дані до файлу туди і надсилати копію через інше ssh-посилання, з іншого боку якого просто записує дані у файл. Точний вуду, який я вимагаю, я залишу читачеві як вправу, оскільки зараз не встигаю грати (вибачте). Цей метод працює лише в тому випадку, якщо друге призначення є загальнодоступним через SSH, що може бути не так, як ви описуєте його як клієнтську машину.

Інший підхід, який менш "запустити і чекати", але в іншому випадку може бути простішим, його використовувати rsyncміж сервером і клієнтом B. Перший раз, коли ви запустите це, він може отримати часткову копію даних, але ви можете просто повторно запустити його, щоб отримати більше даних після цього (з одним остаточним запуском після завершення передачі Client1-> Server). Це буде працювати лише в тому випадку, якщо сервер під час передачі SFTP передає дані прямо у правильне ім'я файлу (іноді ви побачите дані, що переходять у тимчасовий файл, який потім перейменовують, коли файл повністю передається - це робиться для того, щоб зробити оновлення файлів більш атомне, але зробить ідею rsync непридатною). Ви також можете використовувати rsync для передачі C1-> S замість scp (якщо ви використовуєте--inplaceваріант уникнути згаданої вище проблеми) - використання rsync також захистить вас від необхідності повторного повторного повторного використання, якщо підключення C1-> сервера має проблеми під час великої передачі (я, як правило, використовую rsync --inplace -a --progress <source> <dest>замість scp / sftp, коли rsync доступний, для ця поведінка "передачі резюме").

Підсумовуючи сказане, виконуючи:

rsync --inplace -a --progress <source> user@server:/<destination_file_or_folder>

на client1, потім працює

rsync --inplace -a --progress user@server:/<destination_file_or_folder> <destination_on_cli2>

на client2 кілька разів, поки перша передача не буде завершена (потім ще раз запустіть, щоб переконатися, що у вас все). rsyncдуже добре лише передавати абсолютний мінімум, який потрібно оновлювати місце, а не передавати весь лот кожен раз. Для параноїя ви, можливо, захочете додати --checksumпараметр до команд rsync (це займе набагато більше часу для процесора для великих файлів, але не призведе до значного перенесення даних, якщо це не потрібно), а для швидкості --compressопція допоможе, якщо дані ви переносите вже не у стисненому форматі.


5

Я не можу спробувати його на даний момент, тому це може цілком провалитись: моя ідея така: встановіть каталог, куди файл надходить у клієнт B, наприклад, з sshfs до / mnt / server у файловій системі клієнта b. Потім

tail -c +0 -f /mnt/server/thefileinquestion > ~/finalfile

/ usr / bin / tail: не вдається відкрити `+0 'для читання: Немає такого файлу чи каталогу - coreutils 7.4
maxschlepzig

Вибачте, відсутній -c. Я це зафіксував у відповіді вище.
fschmitt

ОК, проблема, яку я бачу в цьому, полягає в тому, що команда не закінчується (-f -> follow ...). Ви повинні видати sigQUIT або щось подібне, коли ви впевнені, що ці запитання повністю написані. Btw, залежно від версії хвоста та fs, хвіст внутрішньо проводить опитування файлу (наприклад, щосекунди).
maxschlepzig

У мене був випадок: запис відеофайлу на мій жорсткий диск, але я хотів скопіювати його на зовнішню флеш-пам'ять USB, щоб я міг роздати його людині, як тільки запис припиниться. Я спробував кілька, rsync --appendа потім перевірив, md5sumале файли ніколи не відповідали. tail -c +0зробив роботу за мене. Я також pv -pteraконтролював хід хвоста, він дозволяє мені бачити, чи працює він. Я ще не закінчив перевіряти md5, щоб перевірити, чи працює він, але виглядає чудово.
недобре

@unfa Будь ласка, оновіть свій коментар, додавши відповідь нижче (тобто не коментар).
Xofo

1

Я думаю, що це має спрацювати:

user@clientA:~$ cat file | ssh server "cat > dest"

і потім

user@clientB:~$ ssh server "tail +0 -f dest" > file

Додайте команду pv, якщо ви хочете побачити свою пропускну здатність.


Ти мав на увазі писати tail -c +0?
десерт

1

Ви можете використати для цього фіфо. Для простоти спочатку без ssh лише два xterms:

У xterm A:

$ mkfifo fif
$ cat test.tar.gz | tee copy.tar.gz > fif

У xterm B:

$ cat fif > dest.tar.gz
$ cmp test.tar.gz dest.tar.gz
$ echo $?
0
$ cmp test.tar.gz copy.tar.gz
$ echo $?
0

З ssh він повинен бути чимось у цих рядках - можливо, вам доведеться вимкнути символ втечі в ssh (-e none):

клієнт A:

 $ ssh server mkfifo fif
 $ cat src.tar.gz | ssh "tee fif > copy.tar.gz"

клієнт B:

 $ ssh server cat fif > dest.tar.gz

1

У мене ситуація, яка потребує рішення, як запитували оригінальні афіші. Я записую хокейну гру на своєму комп’ютері в одному місці, і я хотів би подивитися її на своєму телевізорі в іншому місці. Посилання між двома місцями дозволяє копії йти зі швидкістю 1,3 Мбіт / с, а відеозапис - близько 1,5 Мбіт / с. Отже, я хочу скопіювати файл, коли він починає записувати. Таким чином моя 3-годинна гра буде копіювати приблизно за 3,5 години. Отже, я копіюю його під час запису, і я можу почати його перегляд через 30 хвилин після його запуску. Тоді я можу спостерігати за цим без перерв, майже в режимі реального часу. Тобто, поки я можу змусити її скопіювати як написання нового файлу. Проблема з такими інструментами, як rsync та scp, полягає в тому, що вони дивляться на розмір файлу, коли ви ініціюєте копію та як тільки вона копіює таку кількість даних, вона закривається; навіть якщо файл виріс більш ніж удвічі під час цієї копії. І якщо я просто використовую rsync в циклі, щоб скопіювати його, як тільки він зупиниться, коли наступний rsync закінчить, він відновлює цільовий файл, і це вбиває мій відеоплеєр, і я повинен перезапустити його перегляд і перейти вперед, куди б я не був в програмі, коли раптом її вбили. Я хотів кращого рішення, і не зміг його знайти, тому замість цього я зібрав це:

dd if=2031_20160514030000.mpg |
pv --size 4653819304 |
ssh -C -c arcfour,blowfish-cbc -p 5555 myserver.com 'dd of=/media/TV/2031_20160514030000.mpg'

Отже, що це робить?

По-перше, я використовую dd, щоб скопіювати файл у міру його зростання. Оскільки файл росте швидше, ніж DD може надсилати його по мережі, dd ніколи не застає до кінця файлу. Далі я передаю його в "переглядач труб (pv)", і я даю йому оцінку того, наскільки великий файл буде базуватися на тому, наскільки зазвичай ці файли зазвичай є. Це не обов'язково, але мені подобається бачити показник прогресу. Потім я передаю потік моєму ssh-з'єднанню. Ssh-з'єднання використовується -Cдля стиснення (щоб зменшити пропускну здатність мережі та спробувати пришвидшити її), -c arcfour,blowfish-cbcдля найменш дорогого шифрування (знову ж таки, щоб трохи прискорити роботу),-pпризначений для мого порту брандмауера, який я використовую в пункті призначення, і ssh нарешті запускає команду dd на ціль, щоб відтворити файл під час його отримання. Я радий сказати, що це рішення чудово працює. Я можу спостерігати за хокейною грою, коли файл створюється та копіюється лише з невеликою затримкою.


0

Я не впевнений, що працює хвіст -f метод (хоча це, мабуть, так, якщо файл є текстовим). Причина в тому, що я не знаю, як хвости -f і sftp передають і покладаються на метаінформацію.

Якщо sftp спочатку передає метаінформацію, а хвіст -f покладається на метаінформацію, щоб сказати, що більше немає файлу, то хвіст може погано закінчитися EOF або null.

Якщо вас не хвилює шлях завантаження, тобто Комп'ютер 1 завантажує на комп'ютер 2 завантаження на комп'ютер 3, то ви можете спробувати використовувати верхній бітторент замість sftp. Здається, саме для цього він і був розроблений.


0

Ви можете спробувати прочитати файл з самого початку, але вам потрібно бути впевненим, що ви можете принаймні записати його з однаковою швидкістю.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.