scp или sftp копируют несколько файлов одной командой

314

Я хотел бы скопировать файлы с / на удаленный сервер в разных каталогах. Например, я хочу запустить эти 4 команды одновременно.

scp remote:A/1.txt local:A/1.txt
scp remote:A/2.txt local:A/2.txt
scp remote:B/1.txt local:B/1.txt
scp remote:C/1.txt local:C/1.txt

Какой самый простой способ сделать это?

user987654
источник
14
Когда я делал скрипт, мне приходилось ставить пароль для каждой команды. Могу ли я избежать этого?
user987654
11
Избегайте повторения пароля следующим образом: scp remote: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" local: ./
JohnMudd
У stackoverflow.com/a/23748561/874188 (назначенный как дубликат этого) есть хорошая дополнительная техника.
tripleee
2
Я бы посоветовал вам взглянуть на них rsync, может быть, это поможет вам в этом и во многих будущих случаях. Тогда, чтобы не вводить пароли ( не говоря уже несколько раз) , вы должны прочитать о sshгосударственных / частных ключей, например digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
mnagel
1
Пример на основе ответа @JohnMudd «s: scp root@192.168.56.120:'/etc/openvpn/ca.crt /etc/openvpn/client/client0.crt /etc/openvpn/client/client0.key /etc/openvpn/client/ta.key' ./.
Эдуардо Лусио

Ответы:

421

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

$ scp your_username@remote.edu:/some/remote/directory/\{a,b,c\} ./

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

$ scp foo.txt bar.txt your_username@remotehost.edu:~
$ scp {foo,bar}.txt your_username@remotehost.edu:~
$ scp *.txt your_username@remotehost.edu:~

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

$ scp your_username@remote1.edu:/some/remote/directory/foobar.txt \
your_username@remote2.edu:/some/remote/directory/

Источник: http://www.hypexr.org/linux_scp_help.php

ios.id0
источник
5
Первая команда пропустила окончание «.», А «{a, b, c}» равно \ {a, b, c \}.
duleshi
11
Я думаю, что OP пытается скопировать несколько файлов из нескольких локальных папок в несколько удаленных папок, эти примеры не будут работать, так как все они будут scp файлы ~или ./только.
aesede
20
Осторожно: без запятых в фигурных скобках. Я просто потратил 10 минут, пытаясь выяснить, почему моя команда не работает, и это было из-за пробелов.
Дипак
13
@duleshi {a, b, c} не совсем равен \ {a, b, c \} при копировании с удаленного на локальный, для первого требуется пароль для каждого файла, в то время как для второго требуется пароль только один раз.
Марсело Вентура
15
@MarceloVentura, @duleshi: Кроме того, я хотел бы добавить, что при использовании \{a,b,c\}будет передаваться файлы в одном соединении / пакете (так как они будут расширены на удаленном хосте), в то время как использование {a,b,c}откроет несколько подключений, и накладные расходы будут довольно заметно при передаче большого количества файлов
omninonsense
140

С локального на сервер:

scp file1.txt file2.sh username@ip.of.server.copyto:~/pathtoupload

С сервера на локальный:

scp -T username@ip.of.server.copyfrom:"file1.txt file2.txt" "~/yourpathtocopy"

Gtr_py
источник
6
Это должен быть ответ сверху, так как сервер не запрашивает пароль для каждого файла :)
motagirl2
Не работает на клиенте на Ubuntu 18 (Zsh). Не уверен, где это должно работать. `` `(venv) ➜ git: (master) ✗ scp root @ 172.29..xxx.yyy:" / usr / local / bin / kubectl /root/.kube/config "/ tmp / root @ 172.29..xxx. пароль yyy: ошибка протокола: имя файла не соответствует запросу `` `
jseguillon
3
@ motagirl2 Верхний ответ не запрашивает пароль для каждого файла, если вы выходите из фигурных скобок с обратной косой чертой. Этот ответ дает мне ошибку, что файл не может быть найден.
Плутон
1
@jseguillon Добавьте -Tопцию, чтобы подавить эту ошибку.
Восстановите Монику
1
второй работает на моих машинах, но только без опции -T
Ричард ДиСалво
71

Вы можете копировать целые каталоги, используя -rпереключатель, поэтому, если вы можете изолировать свои файлы в собственный каталог, вы можете скопировать все сразу.

scp -r ./dir-with-files user@remote-server:upload-path

scp -r user@remote-server:path-to-dir-with-files download-path

так например

scp -r root@192.168.1.100:/var/log ~/backup-logs

Или, если их всего несколько, вы можете использовать:

scp 1.txt 2.txt 3.log user@remote-server:upload-path
Иржи Кремсер
источник
Работает ли это, если мой пункт назначения - root, и я делаю каталог etc, например, так: scp -r / backups / etc root @ linuxbox: / где мой источник - очень разреженный каталог с такими вещами, как «hosts» и nginx / sites -доступно и т. д.?
Томати
47

Как упоминал Джири, вы можете использовать scp -r user@host:/some/remote/path /some/local/pathдля рекурсивного копирования файлов. Предполагается, что существует один каталог, содержащий все файлы, которые вы хотите перенести (и больше ничего).

Однако SFTP предоставляет альтернативу, если вы хотите передавать файлы из нескольких разных каталогов, а места назначения не идентичны:

sftp user@host << EOF
  get /some/remote/path1/file1 /some/local/path1/file1
  get /some/remote/path2/file2 /some/local/path2/file2
  get /some/remote/path3/file3 /some/local/path3/file3
EOF

При этом используется синтаксис "here doc" для определения последовательности команд ввода SFTP. В качестве альтернативы вы можете поместить команды SFTP в текстовый файл и выполнитьsftp user@host -b batchFile.txt

ALEV
источник
3
Это единственный ответ, который на самом деле отвечает на вопрос. Спасибо. Я scpслишком долго гуглял и анализировал руководство, пытаясь найти эту функцию, и, думаю, у scp ее нет.
Судо
1
Это, кажется, лучший, самый гибкий ответ. Примечание: меня запутали, пока я не понял, что мне нужно использовать полный путь, как /home/vagrant/Code/вместо ~/Code/.
Райан
Это лучший ответ, просто не забудьте добавить - rдля каталогов
Chris_Rands
25

Ответы с {file1,file2,file3}работает только с bash (удаленно или локально)

Настоящий путь это:

scp user@remote:'/path1/file1 /path2/file2 /path3/file3' /localPath
Vouze
источник
1
Фантастика! Иногда я использую небашевые оболочки, и это неизмеримо помогает. Не только реальный путь, но и правильный путь.
Пол Б.
1
Суетиться с {…, …, …}работами во многих снарядах не только в Баше. Однако это работает в любой оболочке, так что явно лучше.
Петр Доброгост
Нужно больше цитирования. Эти пути могут содержать пробелы.
Амит Найду
1
Вот и мы! Я бы сказал это много раз, но я могу сделать это один раз! Спасибо, Вауз!
Андре Пачеко,
17

Поработав некоторое время с scp, я нашел самое надежное решение:

(Остерегайтесь одинарных и двойных кавычек)

От локального к удаленному:

scp -r "FILE1" "FILE2" HOST:'"DIR"'

Удаленный к местному:

scp -r HOST:'"FILE1" "FILE2"' "DIR"

Обратите внимание, что все, что после "HOST:" будет отправлено на удаленный компьютер и проанализировано там. Поэтому мы должны убедиться, что они не обрабатываются локальной оболочкой. Вот почему вводятся одинарные кавычки. Двойные кавычки используются для обработки пробелов в именах файлов.

Если все файлы находятся в одном каталоге, мы можем использовать *, чтобы сопоставить их все, например:

scp -r "DIR_IN"/*.txt HOST:'"DIR"'
scp -r HOST:'"DIR_IN"/*.txt' "DIR"

По сравнению с использованием синтаксиса "{}", который поддерживается только некоторыми оболочками, этот универсальный

eosphorox
источник
Спасибо за помощь с пробелами в именах файлов. Я использовал подход {}, поэтому мне также пришлось избегать их с \ после цитирования.
Ноумен
3
В случае, если вы хотите использовать символ тильды (~) для вашего домашнего каталога в путях. Обратите внимание, что ~ и / должны быть вне кавычек. `` `scp -r robwaa@192.168.1.101: '~ /" bin / set-vpn-kill-switch "~ /" bin / flush-iptables "' ~ /" "` ``
Роб Ваа
{}Синтаксис делает его проще скопировать несколько файлов из одной директории, есть ли способ сделать это с помощью scp -rтак , что "FILE1" "FILE2"могут быть относительные пути и не абсолютные пути к файлам?
дтасев
15

Самый простой способ

local$ scp remote:{A/1,A/2,B/3,C/4}.txt ./

Таким образом, список {..} может включать каталоги (здесь A, B и C - это каталоги; «1.txt» и «2.txt» - это имена файлов в этих каталогах).

Хотя он скопировал бы все эти четыре файла в один локальный каталог - не уверен, что это то, что вы хотели.

В приведенном выше случае вы получите удаленные файлы A / 1.txt, A / 2.txt, B / 3.txt и C / 4.txt, скопированные в один локальный каталог с именами файлов ./1.txt, ./2.txt, ./3.txt и ./4.txt

Tagar
источник
Не перезаписывает ли это содержимое A / 1.txt содержимым B / 1.txt на локальном компьютере?
Ив Дорфсман
Хороший вопрос ... скорректированный пример (так что теперь он не будет перезаписывать) и добавленное описание. Спасибо.
Тагар
Подобные расширения скобок являются функцией Bash и не переносятся, например, в POSIX sh.
tripleee
1
@tripleee, спасибо. это может быть не posix, но он работает не только в bash. Я все время использую ksh, и он там тоже работает.
Тагар
1
Вы также можете смешать папки и файлы, выполнив:local$ scp -r remote:{A/1.txt,A/2.txt,B/3.txt,C/4.txt,D,F} ./
donhector
13

Проблема : Копирование нескольких каталогов с удаленного сервера на локальный компьютер с помощью одной команды SCP и сохранение каждого каталога, как он есть на удаленном сервере.

Решение : SCP может сделать это легко. Это решает надоедливую проблему ввода пароля несколько раз при использовании SCP с несколькими папками. Следовательно, это также экономит много времени!

например

# copies folders t1, t2, t3 from `test` to your local working directory
# note that there shouldn't be any space in between the folder names;
# we also escape the braces.
# please note the dot at the end of the SCP command

~$ cd ~/working/directory
~$ scp -r username@contact.server.de:/work/datasets/images/test/\{t1,t2,t3\}  .

PS: мотивировано этим великолепным ответом: scp или sftp копируют несколько файлов одной командой


Судя по комментариям, это также хорошо работает в Git Bash на Windows

kmario23
источник
3
PS не добавляйте пробелы между элементами. то есть \ {t1, t2, t3 \} ------> Я потратил десять минут здесь ... LOL
Kenberkeley
1
Это лучший ответ, потому что когда вы выходите из скобок, он будет интерпретироваться как отдельная команда и не будет запрашивать пароль для каждой передачи
Amaynut
@ Amaynut да, именно так! Это, безусловно, экономит много времени и усилий :)
kmario23
12

Скопируйте несколько каталогов:

scp -r dir1 dir2 dir3 admin@127.0.0.1:~/
yuliskov
источник
Вопрос был в том, как скопировать из удаленного каталога в локальный, а не наоборот.
Тагар
5

Вы можете сделать это так:

scp hostname@serverNameOrServerIp:/path/to/files/\\{file1,file2,file3\\}.fileExtension ./

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

Убедитесь, что не ставьте пробелы между именами файлов, используйте только запятую ,.

J_rad
источник
1
Это хорошо, когда расширение такое же. Это может быть написано так, как /path/to/files/\\{file1.ext,file2.ext,file3.ext\\}будто файлы имеют разные расширения. Примечание для людей PowerShell (теперь, когда MS присоединился к вечеринке), вы должны использовать `вместо этого побег:/path/to/files/`{file1.ext,file2.ext,file3.ext`}
dtasev
3

ПРИМЕЧАНИЕ: заранее прошу прощения за ответ только на часть вышеупомянутого вопроса. Однако я обнаружил, что эти команды полезны для моих текущих потребностей Unix.

Загрузка определенных файлов с локального компьютера на удаленный компьютер:

~/Desktop/dump_files$ scp file1.txt file2.txt lab1.cpp etc.ext your-user-id@remotemachine.edu:Folder1/DestinationFolderForFiles/

Загрузка всего каталога с локального компьютера на удаленный компьютер:

~$ scp -r Desktop/dump_files your-user-id@remotemachine.edu:Folder1/DestinationFolderForFiles/

Загрузка всего каталога с удаленного компьютера на локальный:

~/Desktop$ scp -r your-user-id@remote.host.edu:Public/web/ Desktop/

fat43r 80ard
источник
3

В моем случае я ограничен только использованием команды sftp.
Итак, мне пришлось использовать пакетный файл с sftp. Я создал такой скрипт, как следующий. Предполагается, что вы работаете в каталоге / tmp и хотите поместить файлы в destdir_on_remote_system в удаленной системе. Это также работает только с неинтерактивным логином. Вам необходимо настроить открытый / закрытый ключи, чтобы вы могли войти без ввода пароля. Изменить по мере необходимости.

#!/bin/bash

cd /tmp
# start script with list of files to transfer
ls -1 fileset1* > batchfile1
ls -1 fileset2* >> batchfile1

sed -i -e 's/^/put /' batchfile1
echo "cd destdir_on_remote_system" > batchfile
cat batchfile1 >> batchfile
rm batchfile1

sftp -b batchfile user@host
dminear
источник
2

Ваша команда работает отлично, но я также хочу изменить имя файла при отправке с локального на удаленный. Я написал команду: - sshpass -p пароль scp /path/to/file.txt root @ hostname: /path/newfile.txt

Но выдает ошибку, что /path/newfile.txt: не найден такой файл или каталог, плз, помогите мне в этой ситуации

Решми КЦ
источник
Убедитесь, что удаленный каталог hostname:/path/действительно существует и доступен.
Амит Найду
1

scp использует ssh для передачи данных с той же аутентификацией и обеспечивает ту же безопасность, что и ssh.

Лучшей практикой здесь является реализация «SSH KEYS И PUBLIC KEY AUTHENTICATION». Благодаря этому вы можете писать свои сценарии, не беспокоясь об аутентификации. Просто как тот.

Посмотрите, что такое SSH-KEYGEN

аугусто
источник
1

В конкретном случае, когда все файлы имеют одинаковое расширение, но с разным суффиксом (скажем, номером файла журнала), вы используете следующее:

scp user_name@ip.of.remote.machine:/some/log/folder/some_log_file.* ./

Это скопирует все файлы с именем some_log_file из заданной папки на удаленном компьютере, то есть - some_log_file.1, some_log_file.2, some_log_file.3 ....

Гай Авраам
источник
-1
scp remote:"[A-C]/[12].txt" local:
unxnut
источник
спасибо, но это всего лишь пример, а фактическое имя файла или каталога более сложное. Но у меня есть их список.
user987654
Можете ли вы описать их с помощью регулярного выражения?
unxnut
Можно ли сохранить ту же структуру каталогов в целевом каталоге с помощью регулярного выражения?
user987654
1
Да, вы должны быть в состоянии сделать это с -rопцией scp. И вы можете сохранить другие атрибуты (например, отметку времени) с -pопцией.
unxnut