scp або sftp скопіюйте кілька файлів за допомогою однієї команди


313

Я хотів би скопіювати файли з / на віддалений сервер у різні каталоги. Наприклад, я хочу запустити ці 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

Який найпростіший спосіб зробити це?


14
Коли я робив сценарій, я повинен був поставити пароль для кожної команди. Чи можу я цього уникнути?
користувач987654

11
Уникайте повторення пароля таким чином: scp remote: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" локальний: ./
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' ./.
Едуардо Лусіо

Відповіді:


419

Скопіюйте кілька файлів з віддаленого на локальний:

$ 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


5
Перша команда опустила закінчення ".", А "{a, b, c}" дорівнює \ {a, b, c \}.
дулеші

11
Я думаю, що ОП намагається скопіювати декілька файлів у декілька локальних папок у декілька віддалених папок, ці приклади не спрацюють, оскільки всі вони будуть робити 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"


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: / де мій джерело - дуже рідкий каталог з такими речами, як "господарі" та nginx / сайти -доступні тощо?
Томачі

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

Для цього використовується синтаксис "тут doc" для визначення послідовності команд введення SFTP. Як альтернативу, ви можете помістити команди SFTP у текстовий файл та виконатиsftp user@host -b batchFile.txt


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

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"

Порівняно з використанням синтаксису "{}", який підтримується лише деякими оболонками, цей універсальний


Дякуємо за допомогу з пробілами у назвах файлів. Я використовував {} підхід, тому мені також довелося уникати їх з \ після цитування.
Ноумен

3
У випадку, якщо ви хочете використовувати символ "tilde" (~) для вашого домашнього каталогу в шляхах. Зверніть увагу, як ~ та / повинні бути поза лапок. `` `scp -r robwaa@192.168.1.101: '~ /" bin / set-vpn-kill-switch "~ /" bin / flush-iptables "' ~ /" "` ``
Rob

{}Синтаксис робить його простіше скопіювати декілька файлів з однієї директорії, чи є спосіб зробити це з допомогою scp -rтак , що "FILE1" "FILE2"можуть бути відносні шляхи і не абсолютні шляхи до файлів?
dtasev

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


Чи не буде це перезаписано вміст A / 1.txt із вмістом B / 1.txt на локальній машині?
Ів Дорфсман

хороший момент .. скоригований приклад (так що тепер це не перезапишеться) та додано опис Дякую.
Тагар

Подібні розширення дужок є функцією Bash, і не переноситься, наприклад, POSIX sh.
tripleee

1
@tripleee, спасибі це може бути не позикс, але він працює не тільки в баші. Я постійно використовую 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


3
PS не додають пробіли між елементами. тобто \ {t1, t2, t3 \} ------> Я витратив десять хвилин тут ... lol
kenberkeley

1
Це найкраща відповідь, тому що, коли ви уникнете дужок, вона буде трактована як одна команда, і вона не запитуватиме пароль для кожної передачі
Amaynut

@Amaynut так, точно! Це, безумовно, економить багато часу та сил :)
kmario23

12

Скопіюйте кілька каталогів:

scp -r dir1 dir2 dir3 admin@127.0.0.1:~/

Питання полягало в тому, як скопіювати з віддаленого каталогу в локальний, а не навпаки.
Тагар

5

Можна зробити так:

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

Це завантажить усі перелічені імена файлів у будь-який локальний каталог, у якому ви знаходитесь.

Переконайтеся, що не розміщуйте пробіли між кожним іменем файлу, використовуйте лише коми ,.


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/


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

2

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

Але це дає помилку, що /path/newfile.txt: не знайдено жодного файлу чи каталогу у цій ситуації


Переконайтесь, що віддалений каталог hostname:/path/фактично існує та є доступним.
Аміт Найду

1

scp використовує ssh для передачі даних з тією ж автентифікацією та забезпечує ту ж безпеку, що і ssh.

Найкращою практикою тут є реалізація "КЛЮЧІВ СШ і ПУБЛІЧНИЙ АВТОМЕНТИЧНИЙ КЛЮЧ". За допомогою цього ви можете писати свої сценарії, не турбуючись про автентифікацію. Просто як це.

Дивіться, що таке 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:

спасибі, але це лише приклад, і власне ім’я файлу чи каталогу є складнішим. Але в мене є їх список.
користувач987654

Чи можете ви описати їх звичайним виразом?
unxnut

Чи можливо зберегти ту саму структуру каталогів у цільовому каталозі, використовуючи регулярний вираз?
user987654

1
Так, ви повинні мати змогу зробити це з -rопцією до scp. І ви можете зберегти інші атрибути (наприклад, часова марка) за допомогою -pопції.
unxnut
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.