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?


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 root@192.168.56.120:'/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 your_username@remote.edu:/some/remote/directory/\{a,b,c\} ./

Copie varios archivos de local a remoto:

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

Copie varios archivos de remoto a remoto:

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

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


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 username@ip.of.server.copyto:~/pathtoupload

De servidor a local:

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


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 root@192.168.1.100:/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

¿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


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

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


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 robwaa@192.168.1.101: '~ /" 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


¿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 username@contact.server.de:/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


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 admin@127.0.0.1:~/

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 ,.


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 your-user-id@remotemachine.edu:Folder1/DestinationFolderForFiles/

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

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

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

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


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

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


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


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 user_name@ip.of.remote.machine:/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 ...


-1
scp remote:"[A-C]/[12].txt" local:

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.