Вопрос или проблема
Я использую scp для копирования каталога с одного удаленного сервера в новый каталог (т.е. просто меняя имя) на другом удаленном сервере, как:
scp -prq server1:dir1 server2:dir2
Это работает нормально, если dir2 не существует на server2, создается новый каталог под названием dir2, который содержит все из dir1 на server1.
Проблема возникает, когда dir2 уже существует на server2 (ПРИМЕЧАНИЕ: у меня нет возможности узнать об этом заранее или удалить dir2 на server2 заранее) – в этом случае я получаю копию dir1, называемую dir1, в dir2.
Вот скрипт, который работает для меня:
#!/bin/sh
echo "метод 1"
scp -prq server1:dir1/* server2:dir2/ >/dev/null 2>&1
if [ "$?" -ne "0" ]; then
echo "не удалось ... пытаюсь метод 2"
scp -prq server1:dir1 server2:dir2
fi
exit
Все еще не уверен, как сделать это в одной команде или возможно ли это.
Используйте эту синтаксис с “точкой”:
scp -prq server1:dir1/. server2:dir2/
Это копирует содержимое этого каталога, а не сам каталог. И я думаю, это более переносимо, чем *
глоби.
Как правило, чтобы управлять созданием каталога, нужно использовать завершающий /
, чтобы подразумевать полный путь, но я думаю, что это тогда не создаст каталог, если он не существует:
scp -prq server1:dir1/* server2:dir2/
Это также может пропустить скрытые . файлы из-за расширения * глоби (без некоторой хитрой специфической работы с оболочкой)
Вы можете подойти к этому по-другому с ssh
и tar
.
ssh server1 "cd dir1 && tar -cf - ." | ssh server2 "( mkdir -p dir2; cd dir2 && tar -xf - )"
Но это означает, что трафик идет через вашу локальную машину.
Удалите его с помощью ssh сначала, а затем воссоздайте с помощью scp.
т.е.
в скрипте…
ssh -i ~/.ssh/[private_key] user@server2 “rm -rf dir2; exit;”
scp -prq server1:dir1 server2:dir2
Я сталкивался с точно такой же проблемой, и в итоге я решил это следующим образом: если dir2 – это [STUFF]/parent/child2
, я переименовываю, копирую или связываю dir1 (в зависимости от ситуации) в dir1_child2 на server1, чтобы последний компонент пути тоже был child2
, а затем просто выполняю
scp -prq server1:dir1_child2 server2:[STUFF]/parent
Это работает независимо от того, присутствует ли child2 в родительском каталоге dir2, и счастливо заменяет dir2, если он есть.
Ответ или решение
Чтобы решить проблему замены или создания директории при использовании команды scp
, рассмотрим несколько методов, которые позволят вам избежать ситуации, когда содержимое одной директории оказывается вложено в другую.
Использование scp
с точечной синтаксикой
Одним из простых и эффективных решений является использование синтаксиса с точкой (.
) в команде scp
. Это позволяет скопировать содержимое директории, а не саму директорию. Вот как это выглядит:
scp -prq server1:dir1/. server2:dir2/
В этом случае .
указывает на то, что нужно скопировать все файлы и подкаталоги из dir1
в dir2
. Если dir2
не существует, он будет создан.
Однако важно заметить, что с использованием такого подхода могут возникнуть сложности, если директория dir2
уже существует и содержит файлы. В этом случае, все файлы из dir1
будут скопированы в dir2
, что может привести к возникновению конфликтов имен.
Использование ssh
и tar
для копирования
Ещё один подход, который позволяет избежать подобных проблем, это использование ssh
и tar
. Этот метод выглядит следующим образом:
ssh server1 "cd dir1 && tar -cf - ." | ssh server2 "(mkdir -p dir2 && cd dir2 && tar -xf -)"
Здесь команда tar
используется для создания архива содержимого директории dir1
, который затем распаковывается в директорию dir2
на удаленном сервере. Этот метод удобно применять, так как он не требует загрузки файлов на локальную машину и обеспечивает более гибкое управление директивами создания и замены.
Ранее удаление целевой директории
В некоторых случаях может быть целесообразным удалить целевую директорию перед новым копированием. Хотя вам и не хочется заранее заниматься удалением, это можно автоматизировать:
ssh -i ~/.ssh/[private_key] user@server2 "rm -rf dir2; exit;"
scp -prq server1:dir1 server2:dir2
Однако этот подход требует выполнения команды ssh
, что может быть нежелательным в некоторых ситуациях из соображений безопасности и избыточности.
Переименование директории
Если ни один из вышеупомянутых методов вам не подходит, попробуйте использовать метод переименования директории на сервере-источнике. Например, если вы находитесь в директории [STUFF]/parent/child2
, вы можете создать новую директорию с измененным именем:
scp -prq server1:dir1_child2 server2:[STUFF]/parent
Заключение
Используя описанные стратегии, вы можете эффективно решить проблему копирования директории с помощью scp
в новых условиях. Важно помнить о возможных конфликтах имен и учитывать, нужны ли вам все файлы из директории, или достаточно только содержимого. Ваш выбор будет зависеть от конкретных требований вашего проекта и особенностей операционной среды.