переместить все файлы в локальном каталоге в удаленный каталог

366
klaudia

Я хочу переместить все файлы из локального каталога в удаленный каталог.

И я использую этот код для достижения этого

 SOURCE_FILE=/var/www/oneserver/* TARGET_DIR=/var/www/anotherServer ARCHIEVEFILE=/var/www/archieveServer  /usr/bin/expect<<EOD spawn /usr/bin/sftp -o Port=$PORT $USER@$HOST expect "password:" send "$PASSWORD\r" expect "sftp>" send "put $SOURCE_FILE $TARGET_DIR\r" expect "sftp>" send "bye\r" EOD  

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

Я также хочу переместить уже отправленный файл в ARCHIEVEFILE с помощью команды mv. Но не понимаю, как его переместить. Я не могу использовать, scpпотому что удаленный сервер не может использовать базовый порт, и единственный способ - использовать sftp.

Кто-нибудь может помочь, пожалуйста?

[РЕДАКТИРОВАТЬ]

$ARCHIEVEFILEеще локальный сервер, только для резервного копирования / перемещения так что эти файлы не отправляются больше со следующим cronjob

TARGET_DIRявляется удаленным сервером.

0
Что написано * «переместить все файлы из локального каталога в удаленный каталог» * - Вы действительно хотите ** переместить ** файлы? Или вы действительно хотите ** скопировать ** их? Martin Prikryl 6 лет назад 0
Разве не весь ваш вопрос касается только перемещения загруженных файлов в * локальную * архивную папку - т.е. ваш вопрос на самом деле не имеет ничего общего с SFTP? Martin Prikryl 6 лет назад 0
Я обновляю свой вопрос. Пожалуйста, посмотрите. Настоящая проблема, с которой я сталкиваюсь в этом сценарии, заключается в том, что он отправляет только некоторые файлы, а не все файлы. klaudia 6 лет назад 0
"это только отправить некоторые файлы" - какие-либо сообщения об ошибках или журналы? Kamil Maciorowski 6 лет назад 0
@Kamil Нет, когда я запускаю скрипт bash вручную, он просто останавливается после загрузки последнего файла, который на самом деле все еще остается. klaudia 6 лет назад 0
Я действительно хочу выяснить, в чем проблема. klaudia 6 лет назад 0
Все файлы имеют одинаковое содержание и одинаковый формат заголовка. klaudia 6 лет назад 0
Примечание: глобализация оболочки и используемые вами кавычки делают ваш код подверженным ошибкам, связанным с пробелами в именах файлов и т. Д. Я не уверен, что в этом случае это действительно проблема. Kamil Maciorowski 6 лет назад 0
Для меня есть две возможности, почему это происходит. Потерянное соединение или он попытался снова отправить тот же файл и завершить его - вот почему я хочу, чтобы команда `rm` работала. но `rm` все еще не работал там. klaudia 6 лет назад 0
предложение: настройте ssh с ключами (без паролей) и используйте scp в скрипте :) Drako 6 лет назад 0

3 ответа на вопрос

2
Martin Prikryl

В OpenSSH нет команды sftpдля перемещения файлов в удаленный каталог.

Что вы можете сделать, это:

  • используйте sftp putдля загрузки файлов (как вы уже делаете), а затем
  • используйте команду shellrm для удаления файлов после того, sftpкак сделано (т.е. после EOD):

    rm $SOURCE_FILE 

    Или используйте !для выхода из sftpоболочки сценарий после отправки put:

    send "!rm $SOURCE_FILE\r" expect "sftp>"  

Конечно, это не атомарное решение. Если файл добавлен между putи rm, он будет потерян. Для атомарного решения вы должны перебирать файлы в локальном каталоге, загружать и удалять их один за другим. Также для надежного решения вам необходимо проверить, была ли загрузка успешной.

Привет, большое спасибо за помощь. Как видите, я использую `send` и` Ожидаем` при выполнении команды, как вставить туда эту команду `rm`. Можете ли вы сказать мне, пожалуйста. хе-хе klaudia 6 лет назад 0
Смотрите мой обновленный ответ. Martin Prikryl 6 лет назад 0
Хорошо, возможно я действительно неправильно понял ваш вопрос. Martin Prikryl 6 лет назад 0
Нет, но ваш ответ все правильно. Но эта строка `send"! Rm $ SOURCE_FILE \ r "` не удаляет файлы после успешной отправки. klaudia 6 лет назад 0
И еще одна проблема, с которой я сталкиваюсь в этом скрипте, заключается в том, что иногда отправляются только некоторые файлы, а не все файлы в каталоге. иногда только 3, иногда только 5, как будто есть что-то, что завершает процесс, который я не знаю, что / klaudia 6 лет назад 0
Привет, я чувствую, что ты почти помог мне понять это. Ты можешь починить это? klaudia 6 лет назад 0
Так вы пробовали `rm` после` EOD`? Martin Prikryl 6 лет назад 0
Я боюсь, что он удалит все файлы, не зная, что он успешно перенесен на удаленный сервер. klaudia 6 лет назад 0
Но в этом отношении нет никакой разницы между этими двумя подходами. Martin Prikryl 6 лет назад 0
1
Kamil Maciorowski

Следующий подход может многое упростить:

  1. Используйте sshfsдля монтирования удаленных общих ресурсов в качестве локальных путей.
  2. Работайте с cpи / или, mvкак если бы все операции были локальными.

Сравните этот мой ответ .

Вам все еще нужна логика, чтобы определить, cpудалось ли удаленному расположению, только затем mvлокальному архиву; в противном случае повторите попытку или что-то еще. Но теперь вся работа, связанная с SFTP, должна прозрачно выполняться sshfs.

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

После того, как вы смонтируете удаленный общий ресурс, например, в /mnt/a b/remote, это будет намного легче обрабатывать.

(Примечание. Рекомендуется использовать имена переменных в нижнем регистре ).

  • Монтировать:

    sshfs -p $port $user@$host:"/path/on/the/remote/host/" "/mnt/a b/remote/" 

    Используйте аутентификацию на основе ключей или прочитайте имя пользователя и пароль в командной строке с помощью sshfs . Читайте о проблемах безопасности .

  • Заглушка кода для копирования файлов:

    # I deliberately use paths with spaces to show how to handle them for filename in "/source/location with spaces"/*; do cp "$filename" "/mnt/a b/remote/" && mv "$filename" "/archive/location with spaces/" done 

    Это &&гарантирует, что mvбудет работать только в случае cpуспеха.

  • Размонтировать:

    fusermount -u "/mnt/a b/remote/" 
`$ ARCHIEVEFILE` по-прежнему является локальным сервером, просто для резервного копирования / перемещения, чтобы эти файлы больше не отправлялись со следующим cronjob. klaudia 6 лет назад 0
`TARGET_DIR` является удаленным сервером. klaudia 6 лет назад 0
Я обновляю свой вопрос. Пожалуйста, посмотрите. Настоящая проблема, с которой я сталкиваюсь в этом сценарии, заключается в том, что он отправляет только некоторые файлы, а не все файлы. klaudia 6 лет назад 0
Прошу прощения за поздний ответ, я на самом деле все еще не понимаю, как объединить ваш ответ `для имени файла в ...` со сценарием, который у меня есть сейчас `send 'put $ SOURCE_FILE $ TARGET_DIR \ r" `. Насколько я знаю, вы используете метод `cp`, а я использовал методы` put` и `wait`. klaudia 6 лет назад 0
@klaudia Мой подход совершенно другой, и он требует, чтобы вы установили общий ресурс с помощью `sshfs`. Kamil Maciorowski 6 лет назад 0
Это заставит меня узнать, как подключиться к серверу с помощью sshfs, и проверить, можно ли подключиться к определенному порту с этим. Если вы можете указать мне на хороший пример, это будет добавлено ко мне. klaudia 6 лет назад 0
@klaudia Мой ответ теперь расширен. Помните, что `man 1 sshfs` - ваш друг. Kamil Maciorowski 6 лет назад 0
Я не уверен, что такое «монтировать». хе-хе Это возвращает неверную точку монтирования`sshfs -p $ port $ user @ $ host: / "/ my / local / files / in / dir / / remote / dir / to / Transfer" ` klaudia 6 лет назад 0
@klaudia Базовый синтаксис: `sshfs user @ host: dir mountpoint`, например,` sshfs klaudia @ server: / home / klaudia / "/ local mountpoint /, который должен существовать заранее /" `. Kamil Maciorowski 6 лет назад 0
Я пытался это сделать, но он сказал: «Конечная точка транспорта не подключена». klaudia 6 лет назад 0
Давайте [продолжим это обсуждение в чате] (https://chat.stackexchange.com/rooms/76265/discussion-between-klaudia-and-kamil-maciorowski). klaudia 6 лет назад 0
0
Sean Davey

Вы можете заархивировать исходный каталог, который хотите перенести

zip -r -9 /path/to/your/zip_file.zip var/www/oneserver/* 

(-r будет возвращаться в подкаталоги, -9 будет применять максимальное сжатие для более быстрой передачи)

затем скопируйте файл на ваш удаленный сервер

scp /path/to/your/zip_file.zip user@host:/var/www/anotherServer 

а затем разархивировать файл на удаленном сервере

ssh user@host 'unzip /var/www/anotherServer/zip_file.zip' 

(есть много флагов, которые вы можете использовать с unzip, которые вы можете использовать, чтобы перезаписывать или никогда не перезаписывать существующие файлы на вашем удаленном сервере, проверьте man unzip для них, особенно -n -o и -u)

надеюсь, это поможет вам

Похожие вопросы