scp o sftp copia múltiples archivos con un solo comando

314

Me gustaría copiar archivos desde / a un servidor remoto en diferentes directorios. Por ejemplo, quiero ejecutar estos 4 comandos a la vez.

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

Cual es la forma mas fácil de hacer eso?

usuario987654
fuente
14
Cuando hice un script, tuve que poner una contraseña para cada comando. ¿Puedo evitarlo?
user987654
11
Evite repetir la contraseña de esta manera: control remoto scp: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" local: ./
JohnMudd
stackoverflow.com/a/23748561/874188 (nominado como duplicado de este) tiene una buena técnica adicional.
tripleee
2
Te sugiero que eches un vistazo rsync, tal vez pueda ayudarte en este caso y en muchos casos futuros. Luego, para evitar ingresar contraseñas (y mucho menos varias veces), debe leer sobre sshlas claves públicas / privadas, por ejemplo, digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
mnagel
1
Ejemplo basa en respuesta @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

Respuestas:

421

Copie varios archivos de remoto a local:

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

Copie varios archivos de local a remoto:

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

Copie varios archivos de remoto a remoto:

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

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

ios.id0
fuente
55
El primer comando omitió un final ".", Y '{a, b, c}' es igual a \ {a, b, c \}.
duleshi
11
Creo que OP está tratando de copiar múltiples archivos en múltiples carpetas locales en múltiples carpetas remotas, estos ejemplos no harán el trabajo, ya que todos harán scp ~o ./solo archivos .
aesede
20
Cuidado: no hay espacios después de las comas dentro de las llaves. Solo pasé 10 minutos tratando de averiguar por qué mi comando no funcionaba y era por los espacios.
deepak
13
@duleshi {a, b, c} no es exactamente igual a \ {a, b, c \} al copiar de remoto a local, porque el primero requiere contraseña para cada archivo, mientras que el segundo requiere contraseña solo una vez.
Marcelo Ventura
15
@MarceloVentura, @duleshi: Además, me gustaría agregar que el uso \{a,b,c\}transferirá los archivos en una sola conexión / lote (ya que se expandirán en el host remoto), mientras que el uso {a,b,c}abrirá varias conexiones, y la sobrecarga es bastante notable al transferir muchos archivos
omninonsense
140

De local a servidor:

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

De servidor a local:

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

Gtr_py
fuente
66
Esta debería ser la respuesta en la parte superior, ya que el servidor no solicita la contraseña para cada archivo :)
motagirl2
No funciona en el cliente en Ubuntu 18 (zsh). No estoy seguro de dónde debería funcionar. `` `(venv) ➜ git: (master) ✗ scp root @ 172.29..xxx.yyy:" / usr / local / bin / kubectl /root/.kube/config "/ tmp / root @ 172.29..xxx. Contraseña de yyy: error de protocolo: el nombre de archivo no coincide con la solicitud `` `
jseguillon
3
@ motagirl2 La respuesta principal no pide la contraseña para cada archivo, siempre y cuando escapes de las llaves con la barra invertida. Esta respuesta me da un error de que no se puede encontrar el archivo.
Plutón
1
@jseguillon Agregue la -Topción para suprimir ese error.
Restablece a Mónica el
1
el segundo funciona en mis máquinas pero solo sin la opción -T
Richard DiSalvo
71

Puede copiar directorios completos con el -rinterruptor de modo que si puede aislar sus archivos en su propio directorio, puede copiar todo de una vez.

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

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

así por ejemplo

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

O si hay solo algunos de ellos, puede usar:

scp 1.txt 2.txt 3.log user@remote-server:upload-path
Jiri Kremser
fuente
¿Funciona esto si mi destino es root y estoy haciendo el directorio etc como por ejemplo: scp -r / backups / etc root @ linuxbox: / donde mi fuente es un directorio muy escaso con cosas como "hosts" y nginx / sites -disponible etc?
Tomachi
47

Como mencionó Jiri, puede usar scp -r user@host:/some/remote/path /some/local/pathpara copiar archivos de forma recursiva. Esto supone que hay un único directorio que contiene todos los archivos que desea transferir (y nada más).

Sin embargo, SFTP ofrece una alternativa si desea transferir archivos desde múltiples directorios diferentes, y los destinos no son idénticos:

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

Utiliza la sintaxis "here doc" para definir una secuencia de comandos de entrada SFTP. Como alternativa, puede poner los comandos SFTP en un archivo de texto y ejecutarsftp user@host -b batchFile.txt

alev
fuente
3
Esta es la única respuesta que realmente responde la pregunta. Gracias. He estado buscando en Google y analizando el scpmanual durante demasiado tiempo tratando de encontrar esta función, y supongo que scp no la tiene.
sudo
1
Esta parece ser la mejor y más flexible respuesta. Nota: me tropecé hasta que me di cuenta de que necesitaba usar una ruta completa como en /home/vagrant/Code/lugar de ~/Code/.
Ryan
Esta es la mejor respuesta, simplemente no se olvide de agregar - rpara directorios
Chris_Rands
25

Las respuestas {file1,file2,file3}solo funcionan con bash (en forma remota o local)

La forma real es:

scp user@remote:'/path1/file1 /path2/file2 /path3/file3' /localPath
Vouze
fuente
1
¡Fantástico! A veces uso shells que no son bash y esto ayuda muchísimo. No solo de la manera real, sino de la manera correcta.
Paul B.
1
Globbing con {…, …, …}obras en muchos proyectiles, no solo en Bash. Sin embargo, esto funciona en cualquier shell, por lo que es claramente mejor.
Piotr Dobrogost
Necesita más citas. Esos caminos pueden contener espacios.
Amit Naidu
1
¡Aquí vamos! Lo voté muchas veces, ¡pero puedo hacerlo una vez! Gracias Vouze!
André Pacheco
17

Después de jugar con scp por un tiempo, encontré la solución más sólida:

(Cuidado con las comillas simples y dobles)

Local a remoto:

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

Remoto a local:

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

Tenga en cuenta que lo que sea después de "HOST:" se enviará al control remoto y se analizará allí. Por lo tanto, debemos asegurarnos de que el shell local no los procese. Es por eso que aparecen comillas simples. Las comillas dobles se usan para manejar espacios en los nombres de archivo.

Si todos los archivos están en el mismo directorio, podemos usar * para hacerlos coincidir, como

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

En comparación con el uso de la sintaxis "{}", que solo es compatible con algunos shells, esta es universal

eosphorox
fuente
Gracias por ayudar con espacios en los nombres de archivo. Estaba usando el enfoque {}, así que también tuve que escapar de ellos con \ después de la cita.
Noumenon
3
En caso de que desee utilizar el carácter tilde (~) para su directorio de inicio en las rutas. Observe cómo el ~ y / deben estar fuera de las comillas. `` `scp -r [email protected]: '~ /" bin / set-vpn-kill-switch "~ /" bin / flush-iptables "' ~ /" "` ``
Rob Waa
La {}sintaxis facilita la copia de varios archivos desde el mismo directorio, ¿hay alguna forma de hacerlo scp -rpara que "FILE1" "FILE2"puedan ser rutas relativas y no rutas absolutas a los archivos?
dtasev
15

La forma más simple es

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

Entonces, la lista {..} puede incluir directorios (A, B y C aquí son directorios; "1.txt" y "2.txt" son nombres de archivo en esos directorios).

Aunque copiaría estos cuatro archivos en un directorio local, no estoy seguro de si eso es lo que quería.

En el caso anterior, terminará los archivos remotos A / 1.txt, A / 2.txt, B / 3.txt y C / 4.txt copiados en un solo directorio local, con nombres de archivo ./1.txt, ./2.txt, ./3.txt y ./4.txt

Tagar
fuente
¿No sobrescribiría esto el contenido de A / 1.txt con el contenido de B / 1.txt en la máquina local?
Yves Dorfsman
buen punto ... ejemplo ajustado (por lo que ahora no sobrescribiría) y descripción agregada. Gracias.
Tagar
Las expansiones de llaves como esta son una característica de Bash y no son portátiles, por ejemplo, para POSIX sh.
tripleee
1
@tripleee, gracias. Puede que no sea posix, pero funciona no solo en bash. Yo uso ksh todo el tiempo y funciona allí también.
Tagar
1
También puede mezclar directorios y archivos haciendo:local$ scp -r remote:{A/1.txt,A/2.txt,B/3.txt,C/4.txt,D,F} ./
donhector
13

Problema : copiar múltiples directorios del servidor remoto a la máquina local usando un solo comando SCP y retener cada directorio tal como está en el servidor remoto.

Solución : SCP puede hacer esto fácilmente. Esto resuelve el molesto problema de ingresar la contraseña varias veces cuando se usa SCP con varias carpetas. ¡En consecuencia, esto también ahorra mucho tiempo!

p.ej

# 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\}  .

PD: Motivado por esta gran respuesta: scp o sftp copia múltiples archivos con un solo comando


Según los comentarios, esto también funciona bien en Git Bash en Windows

kmario23
fuente
3
PD: no agregue espacios entre los elementos. es decir, \ {t1, t2, t3 \} ------>
Perdí
1
Esta es la mejor respuesta porque cuando escapas de las llaves será interpretado como un solo comando y no va a pedir la contraseña para cada transferencia
Amaynut
@Amaynut sí, exactamente! Eso ciertamente ahorra mucho tiempo y esfuerzo :)
kmario23
12

Copiar múltiples directorios:

scp -r dir1 dir2 dir3 [email protected]:~/
yuliskov
fuente
la pregunta era cómo copiar del directorio remoto al local, no al revés.
Tagar
5

Puedes hacerlo de esta manera:

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

Esto descargará todos los nombres de archivo enumerados en el directorio local en el que se encuentre.

Asegúrese de no poner espacios entre cada nombre de archivo, solo use una coma ,.

J_rad
fuente
1
Esto es bueno cuando la extensión es la misma. Podría escribirse como /path/to/files/\\{file1.ext,file2.ext,file3.ext\\}si los archivos tuvieran extensiones diferentes. Nota para las personas de PowerShell (ahora que MS se ha unido a la fiesta) debe usar `para escapar:/path/to/files/`{file1.ext,file2.ext,file3.ext`}
dtasev
3

NOTA: Pido disculpas de antemano por responder solo una parte de la pregunta anterior. Sin embargo, encontré que estos comandos son útiles para mis necesidades actuales de Unix.

Carga de archivos específicos desde una máquina local a una máquina remota:

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

Cargar un directorio completo desde una máquina local a una máquina remota:

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

Descargar un directorio completo de una máquina remota a una máquina local:

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

fat43r 80ard
fuente
3

En mi caso, estoy restringido a usar solo el comando sftp.
Entonces, tuve que usar un archivo por lotes con sftp. Creé un script como el siguiente. Esto supone que está trabajando en el directorio / tmp y desea colocar los archivos en el sistema destdir_on_remote_system en el sistema remoto. Esto también solo funciona con un inicio de sesión no interactivo. Debe configurar claves públicas / privadas para poder iniciar sesión sin ingresar una contraseña. Cambiar según sea necesario.

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

su comando funciona perfecto, pero también quiero cambiar el nombre del archivo al enviar local a remoto. Escribí un comando: - sshpass -p contraseña scp /path/to/file.txt root @ hostname: /path/newfile.txt

Pero da error que /path/newfile.txt: No se encontró tal archivo o directorio, por favor ayúdenme en esta situación

Reshmi KC
fuente
Asegúrese de que el directorio remoto hostname:/path/realmente exista y sea accesible.
Amit Naidu
1

scp usa ssh para la transferencia de datos con la misma autenticación y proporciona la misma seguridad que ssh.

Una práctica recomendada aquí es implementar "CLAVES SSH Y AUTENTICACIÓN DE CLAVES PÚBLICAS". Con esto, puede escribir sus scripts sin preocuparse por la autenticación. Simple como eso.

Vea QUÉ ES EL TECLADO SSH

augusto
fuente
1

En el caso específico en el que todos los archivos tienen la misma extensión pero con un sufijo diferente (por ejemplo, número de archivo de registro), utilice lo siguiente:

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

Esto copiará todos los archivos llamados some_log_file de la carpeta dada dentro del control remoto, es decir, some_log_file.1, some_log_file.2, some_log_file.3 ...

Guy Avraham
fuente
-1
scp remote:"[A-C]/[12].txt" local:
unxnut
fuente
gracias, pero es solo un ejemplo, y el nombre real del archivo o directorio es más complejo. Pero tengo una lista de ellos.
user987654
¿Puedes describirlos con una expresión regular?
unxnut
¿Es posible preservar la misma estructura de directorio en el directorio de destino mediante el uso de expresiones regulares?
user987654
1
Sí, deberías poder hacerlo con la -ropción de scp. Y puede conservar otros atributos (como la marca de tiempo) con la -popción.
unxnut