2

Сценарий таков: на машине A есть файлы, которые я хочу скопировать на машину C. Машина A не может получить доступ к C напрямую, но может получить доступ к машине B, которая может получить доступ к машине C. Я использую scp для копирования с машины A на B, и затем от B до C.

Машина B имеет ограниченное пространство для хранения, поэтому, когда файлы приходят, мне нужно скопировать их в C и удалить их из B. Вторая копия гораздо быстрее, так что это не проблема с пропускной способностью.

Я мог бы сделать это вручную, но я ленив. Я хотел бы запустить скрипт на B или C, который будет копировать каждый файл в C по окончании каждого. Задание scp запускается из A.

Так что мне нужен способ спросить (желательно из bash-скрипта), если файл X.avi "сделан" копированием. Каждый из этих файлов имеет разный размер, и я не могу предсказать размер или время завершения.

Изменить: кстати, время передачи файла составляет около 1 часа от A до B и около 10 минут от B до C, если масштаб времени имеет значение вообще.

6 ответов6

5

Обычный способ сделать это - сначала скопировать его во временное имя файла, предпочтительно в скрытый файл. Когда копирование заканчивается, скрипт, который делает копию, переименовывает его в не скрытое имя файла.

Затем сценарий на машине B может отслеживать не скрытые файлы.

Сценарий на машине A будет выглядеть примерно так:

for file in `ls *` ; do
    scp $file user@host:~/.${file}.tmp
    ssh user@host "mv ~/.${file}.tmp $file"
done

Хотя это не удовлетворяет желание ОП использовать одну строку

scp * user@host:~/

он выполняет то же самое, а также позволяет машине B передавать каждый файл по завершении, не дожидаясь следующего файла.

2

lsof на машине B показывает, что файл scp открыт? если это так, вы можете посмотреть lsof и увидеть, когда scp закрывает файл. Если нет, вы можете посмотреть размер файла и после того, как он не изменился в течение заданного периода времени (например, 5 минут), скопируйте его из B в C.

Третий вариант - скопировать файлы из A в каталог "in_progress" на C. После того, как копирование закончится на A, выполните команду mv чтобы выйти из каталога "in_progress".

2

Я просто подумал о другом, совершенно не связанном варианте. Не использует scp вообще. Пожалуйста, дайте мне знать, если это будет работать:

  1. на B создайте где-нибудь трубу fifo: mkfifo /tmp /xfer

  2. на A, не используйте scp, вместо этого tar -cz files | ssh B 'cat > /tmp/xfer

  3. на C запустите ssh B 'cat /tmp/xfer' | tar -xz

Таким образом, данные не хранятся на B, они просто проходят через канал. Недостатком является то, что вы можете иметь только одну копию за раз ...

Вам нужно будет убедиться, что процесс на C возрождается при каждом его завершении.

2

Подумав об опубликованных ответах (в частности, об идее @ Джоша по просмотру измененного времени), я пытался запустить манипуляции с файлами B на C. Понимаете, B является анемичным, насколько доступны инструменты, поэтому ничто, казалось, не могло выполнить эту работу был здесь. Я пришел к этому решению. Эта идея не моя, я нашел ее в поиске Google перед этим вопросом. Я отказался от него ранее, поскольку у машины B не было утилиты find .

Сначала смонтируйте соответствующий каталог на B на C, чтобы он отображался как локальная файловая система. Я использовал sshfs для этого (кстати, замечательный инструмент). Это позволит мне использовать утилиты C вместо B.

Во-вторых, команда find /the/folder/* -mmin +5 будет соответствовать всем файлам, измененным более 5 минут назад. Таким образом, команда find /the/folder/* -mmin +5 -exec {} /the/other/folder \; переместит все файлы, которые были изменены более 5 минут назад, в другую папку (которая на самом деле находится на C, вместо sshfs, смонтированного из B.

Наконец, я настроил скрипт cron для запуска вышеуказанного скрипта каждые 10 минут сегодня и завтра. Строка в моем crontab выглядит следующим образом.

*/5 * 22,23 9 * find /the/folder/* -mmin +5 -exec mv {} /the/other/folder \;

Надеюсь, это сработает. Следующий файл еще не закончен, так что я не могу комментировать, действительно ли он работает в сочетании со скриптом cron, но я сделал несколько файлов вручную и посеял их, и они переместились нормально. скрестить пальцы

Изменить: Это работает, хотя, как это было изначально, были некоторые ошибки, теперь они исправлены.

1

Нет необходимости в mkfifo. На машине B запустите это:

ssh A 'tar -cz files' | ssh C 'tar -xz'

Вы можете найти опцию tar -C полезной.

Если вам нужно начать копирование на машине A, просто выполните:

tar -cz files' | ssh B "ssh C 'tar -xz'"

Остерегайтесь правильного цитирования, хотя.

0

Копия будет запущена как другой процесс, или вы можете принудительно запустить его, используя подоболочку. Затем вы можете использовать ps, чтобы "наблюдать" за процессом и видеть, когда он исчезает.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .