scp atau sftp menyalin beberapa file dengan satu perintah

314

Saya ingin menyalin file dari / ke server jauh di direktori yang berbeda. Sebagai contoh, saya ingin menjalankan 4 perintah ini sekaligus.

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

Apa cara termudah untuk melakukan itu?

pengguna987654
sumber
14
Ketika saya membuat skrip, saya harus memasukkan kata sandi untuk setiap perintah. Bisakah saya menghindarinya?
user987654
11
Hindari pengulangan kata sandi dengan cara ini: scp remote: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" local: ./
JohnMudd
stackoverflow.com/a/23748561/874188 (dinominasikan sebagai duplikat yang satu ini) memiliki teknik tambahan yang bagus.
tripleee
2
Saya menyarankan agar Anda melihat-lihat rsync, mungkin dapat membantu Anda dalam kasus ini dan banyak kasus mendatang. Kemudian, untuk menghindari memasukkan kata sandi (apalagi beberapa kali), Anda harus membaca tentang sshkunci publik / pribadi, misalnya digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
mnagel
1
Misalnya berdasarkan jawaban @JohnMudd 's: scp [email protected]:'/etc/openvpn/ca.crt /etc/openvpn/client/client0.crt /etc/openvpn/client/client0.key /etc/openvpn/client/ta.key' ./.
Eduardo Lucio

Jawaban:

421

Salin beberapa file dari jarak jauh ke lokal:

$ scp [email protected]:/some/remote/directory/\{a,b,c\} ./

Salin beberapa file dari lokal ke jarak jauh:

$ scp foo.txt bar.txt [email protected]:~
$ scp {foo,bar}.txt [email protected]:~
$ scp *.txt [email protected]:~

Salin beberapa file dari jarak jauh ke jarak jauh:

$ scp [email protected]:/some/remote/directory/foobar.txt \
[email protected]:/some/remote/directory/

Sumber: http://www.hypexr.org/linux_scp_help.php

ios.id0
sumber
5
Perintah pertama menghilangkan akhiran ".", Dan '{a, b, c}' sama dengan \ {a, b, c \}.
duleshi
11
Saya pikir OP sedang mencoba untuk menyalin beberapa file dalam beberapa folder lokal ke beberapa folder jarak jauh, contoh-contoh ini tidak akan berhasil, karena mereka semua akan scp file ke ~atau ./hanya.
Aesede
20
Hati-hati: tidak ada spasi setelah koma di dalam kurung kurawal. Saya hanya menghabiskan 10 menit untuk mencari tahu mengapa perintah saya tidak berfungsi dan itu karena ruang.
deepak
13
@duleshi {a, b, c} tidak persis sama dengan \ {a, b, c \} ketika menyalin dari jarak jauh ke lokal, untuk yang pertama memerlukan kata sandi untuk setiap file sedangkan yang kedua hanya membutuhkan kata sandi sekali saja.
Marcelo Ventura
15
@MarceloVentura, @duleshi: Juga, saya ingin menambahkan bahwa menggunakan \{a,b,c\}akan mentransfer file dalam satu koneksi / batch (karena mereka akan diperluas pada host jarak jauh), sementara menggunakan {a,b,c}akan membuka banyak koneksi, dan overhead adalah cukup terlihat ketika mentransfer banyak file
omninonsense
140

Dari lokal ke server:

scp file1.txt file2.sh [email protected]:~/pathtoupload

Dari server ke lokal:

scp -T [email protected]:"file1.txt file2.txt" "~/yourpathtocopy"

Gtr_py
sumber
6
Ini harus menjadi jawaban di atas, karena server tidak meminta kata sandi untuk setiap file :)
motagirl2
Tidak bekerja pada klien di Ubuntu 18 (zsh). Tidak yakin di mana ini harus bekerja. `` `(venv) ➜ git: (master) ✗ scp root @ 172.29..xxx.yyy:" / usr / local / bin / kubectl /root/.kube/config "/ tmp / root @ 172.29..xxx. kata sandi yyy: kesalahan protokol: nama file tidak cocok dengan permintaan `` `
jseguillon
3
@ motagirl2 Jawaban teratas tidak meminta kata sandi untuk setiap file selama Anda melarikan diri dari kurung keriting dengan garis miring terbalik. Jawaban ini memberi saya kesalahan karena file tidak dapat ditemukan.
Pluto
1
@ jseguillon Tambahkan -Topsi untuk menekan kesalahan itu.
Pasang kembali Monica
1
yang kedua bekerja di komputer saya tetapi hanya tanpa opsi -T
Richard DiSalvo
71

Anda dapat menyalin seluruh direktori dengan menggunakan -rsakelar sehingga jika Anda dapat mengisolasi file Anda ke direktori sendiri, Anda dapat menyalin semuanya sekaligus.

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

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

jadi misalnya

scp -r [email protected]:/var/log ~/backup-logs

Atau jika jumlahnya hanya sedikit, Anda dapat menggunakan:

scp 1.txt 2.txt 3.log user@remote-server:upload-path
Jiri Kremser
sumber
Apakah ini berfungsi jika tujuan saya adalah root dan saya sedang melakukan direktori dll seperti misalnya: scp -r / backups / root @@boxbox: / di mana sumber saya adalah direktori yang sangat jarang dengan hal-hal seperti "host" dan nginx / sites -Tersedia dll?
Tomachi
47

Seperti yang disebutkan Jiri, Anda dapat menggunakannya scp -r user@host:/some/remote/path /some/local/pathuntuk menyalin file secara rekursif. Ini mengasumsikan bahwa ada satu direktori yang berisi semua file yang ingin Anda transfer (dan tidak ada yang lain).

Namun, SFTP memberikan alternatif jika Anda ingin mentransfer file dari beberapa direktori yang berbeda, dan tujuannya tidak sama:

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

Ini menggunakan sintaks "di sini doc" untuk menentukan urutan perintah input SFTP. Sebagai alternatif, Anda bisa memasukkan perintah SFTP ke file teks dan mengeksekusisftp user@host -b batchFile.txt

alev
sumber
3
Ini satu-satunya jawaban yang benar-benar menjawab pertanyaan itu. Terima kasih. Saya telah Googling dan menganalisis scpmanual terlalu lama mencoba untuk menemukan fitur ini, dan saya kira scp tidak memilikinya.
sudo
1
Ini sepertinya jawaban terbaik, paling fleksibel. Catatan: Saya tersandung sampai saya menyadari bahwa saya perlu menggunakan jalur lengkap seperti /home/vagrant/Code/bukan ~/Code/.
Ryan
Ini adalah jawaban terbaik, tapi jangan lupa untuk menambahkan - rdirektori
Chris_Rands
25

Jawaban dengan {file1,file2,file3}hanya berfungsi dengan bash (pada jarak jauh atau lokal)

Cara sebenarnya adalah:

scp user@remote:'/path1/file1 /path2/file2 /path3/file3' /localPath
Vouze
sumber
1
Fantastis! Saya menggunakan cangkang non-bash kadang-kadang dan ini membantu tak terukur. Bukan hanya cara yang nyata, tetapi cara yang benar.
Paul B.
1
Penuh dengan {…, …, …}karya di banyak cangkang, tidak hanya di Bash. Namun ini bekerja di shell apa pun jadi jelas lebih baik.
Piotr Dobrogost
Perlu lebih banyak mengutip. Jalur tersebut dapat berisi spasi.
Amit Naidu
1
Itu dia! Saya sering mengutarakannya, tetapi saya bisa melakukannya sekali saja! Vouze terima kasih!
André Pacheco
17

Setelah bermain dengan scp untuk sementara waktu saya telah menemukan solusi paling kuat:

(Waspadalah terhadap tanda kutip tunggal dan ganda)

Lokal ke jarak jauh:

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

Jauh ke lokal:

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

Perhatikan bahwa apa pun setelah "HOST:" akan dikirim ke remote dan diurai di sana. Jadi kita harus memastikan mereka tidak diproses oleh shell lokal. Itulah sebabnya tanda kutip tunggal masuk. Tanda kutip ganda digunakan untuk menangani spasi dalam nama file.

Jika semua file ada di direktori yang sama, kita dapat menggunakan * untuk mencocokkan semuanya, seperti

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

Dibandingkan dengan menggunakan sintaks "{}" yang hanya didukung oleh beberapa shell, yang ini bersifat universal

eosphorox
sumber
Terima kasih telah membantu memberi spasi pada nama file. Saya menggunakan pendekatan {} jadi saya juga harus melarikan diri dengan \ setelah mengutip.
Noumenon
3
Jika Anda ingin menggunakan karakter tilde (~) untuk direktori home Anda di jalur. Perhatikan bagaimana ~ dan / harus di luar tanda kutip. `` `scp -r [email protected]: '~ /" bin / set-vpn-kill-switch "~ /" bin / flush-iptables "' ~ /" "` ``
Rob Waa
The {}sintaks membuat lebih mudah untuk menyalin beberapa file dari direktori yang sama, apakah ada cara untuk melakukan hal ini dengan scp -rsehingga "FILE1" "FILE2"dapat path relatif dan path tidak mutlak untuk file?
dtasev
15

Cara paling sederhana adalah

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

Jadi {..} daftar dapat menyertakan direktori (A, B dan C di sini adalah direktori; "1.txt" dan "2.txt" adalah nama file dalam direktori tersebut).

Meskipun itu akan menyalin keempat file ini ke dalam satu direktori lokal - tidak yakin apakah itu yang Anda inginkan.

Dalam kasus di atas Anda akan berakhir file jarak jauh A / 1.txt, A / 2.txt, B / 3.txt dan C / 4.txt disalin ke direktori lokal tunggal, dengan nama file ./1.txt, ./2.txt, ./3.txt dan ./4.txt

Tagar
sumber
Bukankah ini akan menimpa konten A / 1.txt dengan konten B / 1.txt di mesin lokal?
Yves Dorfsman
poin bagus .. contoh disesuaikan (jadi sekarang tidak akan menimpa) dan menambahkan deskripsi. Terima kasih.
Tagar
Ekspansi Brace seperti ini adalah fitur Bash, dan tidak portabel untuk misalnya POSIX sh.
tripleee
1
@ tripleee, terima kasih. itu mungkin bukan posix, tetapi tidak hanya berfungsi di bash. Saya menggunakan ksh sepanjang waktu dan juga berfungsi di sana.
Tagar
1
Anda juga dapat mencampur dir dan file dengan melakukan:local$ scp -r remote:{A/1.txt,A/2.txt,B/3.txt,C/4.txt,D,F} ./
donhector
13

Masalah : Menyalin beberapa direktori dari server jarak jauh ke mesin lokal menggunakan perintah SCP tunggal dan mempertahankan setiap direktori seperti yang ada di server jarak jauh.

Solusi : SCP dapat melakukan ini dengan mudah. Ini memecahkan masalah yang mengganggu memasukkan kata sandi beberapa kali saat menggunakan SCP dengan banyak folder. Akibatnya, ini juga menghemat banyak waktu!

misalnya

# 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 [email protected]:/work/datasets/images/test/\{t1,t2,t3\}  .

PS: Termotivasi oleh jawaban hebat ini: scp atau sftp menyalin beberapa file dengan satu perintah


Berdasarkan komentar, ini juga berfungsi dengan baik di Git Bash pada Windows

kmario23
sumber
3
PS tidak menambahkan spasi di antara item. yaitu \ {t1, t2, t3 \} ------> Saya menyia-nyiakan sepuluh menit di sini ... lol
kenberkeley
1
Ini adalah jawaban terbaik karena ketika Anda melarikan diri dari kawat gigi itu akan ditafsirkan sebagai satu perintah oleh dan itu tidak akan meminta kata sandi untuk setiap transfer
Amaynut
@ Amaynut ya, tepatnya! Itu tentu menghemat banyak waktu dan tenaga :)
kmario23
12

Salin beberapa direktori:

scp -r dir1 dir2 dir3 [email protected]:~/
yuliskov
sumber
pertanyaannya adalah bagaimana menyalin dari direktori jarak jauh ke direktori lokal, bukan sebaliknya.
Tagar
5

Anda bisa melakukan ini:

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

Ini akan mengunduh semua nama file yang terdaftar ke direktori lokal apa pun yang Anda kunjungi.

Pastikan untuk tidak menempatkan spasi di antara setiap nama file hanya menggunakan koma ,.

J_rad
sumber
1
Ini bagus ketika ekstensi sama. Itu dapat ditulis seolah- /path/to/files/\\{file1.ext,file2.ext,file3.ext\\}olah file memiliki ekstensi yang berbeda. Catatan untuk orang-orang PowerShell (sekarang MS telah bergabung dengan pesta) yang perlu Anda gunakan `untuk melarikan diri sebagai gantinya:/path/to/files/`{file1.ext,file2.ext,file3.ext`}
dtasev
3

CATATAN: Saya meminta maaf sebelumnya karena hanya menjawab sebagian dari pertanyaan di atas. Namun, saya menemukan perintah ini berguna untuk kebutuhan unix saya saat ini.

Mengunggah file tertentu dari mesin lokal ke mesin jarak jauh:

~/Desktop/dump_files$ scp file1.txt file2.txt lab1.cpp etc.ext [email protected]:Folder1/DestinationFolderForFiles/

Mengunggah seluruh direktori dari mesin lokal ke mesin jarak jauh:

~$ scp -r Desktop/dump_files [email protected]:Folder1/DestinationFolderForFiles/

Mengunduh seluruh direktori dari mesin jarak jauh ke mesin lokal:

~/Desktop$ scp -r [email protected]:Public/web/ Desktop/

fat43r 80ard
sumber
3

Dalam kasus saya, saya dibatasi hanya menggunakan perintah sftp.
Jadi, saya harus menggunakan batchfile dengan sftp. Saya membuat skrip seperti berikut ini. Ini mengasumsikan Anda bekerja di direktori / tmp, dan Anda ingin meletakkan file di destdir_on_remote_system pada sistem remote. Ini juga hanya berfungsi dengan login non-aktif. Anda perlu mengatur kunci publik / pribadi sehingga Anda dapat masuk tanpa memasukkan kata sandi. Ubah sesuai kebutuhan.

#!/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
sumber
2

perintah Anda berfungsi dengan baik tetapi, saya juga ingin mengubah nama file saat mengirim lokal ke jarak jauh. Saya menulis sebuah perintah: - sshpass -p kata sandi scp /path/to/file.txt root @ hostname: /path/newfile.txt

Tapi itu memberikan kesalahan bahwa /path/newfile.txt: Tidak ada file atau direktori yang ditemukan tolong bantu saya dalam situasi ini

Reshmi KC
sumber
Pastikan direktori jarak jauh hostname:/path/benar-benar ada dan dapat diakses.
Amit Naidu
1

scp menggunakan ssh untuk transfer data dengan otentikasi yang sama dan menyediakan keamanan yang sama dengan ssh.

Praktik terbaik di sini adalah menerapkan "KUNCI SSH DAN OTENTIKASI KUNCI PUBLIK". Dengan ini, Anda dapat menulis skrip tanpa khawatir tentang otentikasi. Sederhana seperti itu.

Lihat APA ITU SSH-KEYGEN

agustus
sumber
1

Dalam kasus khusus di mana semua file memiliki ekstensi yang sama tetapi dengan akhiran yang berbeda (katakanlah jumlah file log) Anda menggunakan yang berikut ini:

scp [email protected]:/some/log/folder/some_log_file.* ./

Ini akan menyalin semua file bernama some_log_file dari folder yang diberikan dalam remote, yaitu- some_log_file.1, some_log_file.2, some_log_file.3 ....

Guy Avraham
sumber
-1
scp remote:"[A-C]/[12].txt" local:
unxnut
sumber
terima kasih, tetapi ini hanyalah sebuah contoh, dan nama file atau direktori sebenarnya lebih kompleks. Tapi saya punya daftar mereka.
user987654
Bisakah Anda menggambarkannya dengan ekspresi reguler?
unxnut
Apakah mungkin untuk mempertahankan struktur direktori yang sama di direktori target dengan menggunakan ekspresi reguler?
user987654
1
Ya, Anda harus dapat melakukannya dengan -ropsi untuk scp. Dan Anda dapat mempertahankan atribut lainnya (seperti cap waktu) dengan -popsi.
unxnut