scp ou sftp copient plusieurs fichiers avec une seule commande


314

Je voudrais copier des fichiers depuis / vers un serveur distant dans différents répertoires. Par exemple, je veux exécuter ces 4 commandes à la fois.

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

Quelle est la façon la plus simple de procéder?


14
Quand j'ai fait un script, j'ai dû mettre un mot de passe pour chaque commande. Puis-je l'éviter?
user987654

11
Évitez de répéter le mot de passe de cette façon: scp remote: "A / 1.txt A / 2.txt B / 1.txt C / 1.txt" local: ./
JohnMudd

stackoverflow.com/a/23748561/874188 (désigné comme doublon de celui-ci) a une belle technique supplémentaire.
tripleee

2
Je suggère que vous jetiez un coup d'œil rsync, peut-être que cela peut vous aider dans ce cas et dans de nombreux cas à venir. Ensuite, pour éviter de saisir des mots de passe (et encore moins plusieurs fois), vous devez lire sshles clés publiques / privées, par exemple digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
mnagel

1
Exemple basé sur la réponse de @JohnMudd: 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

Réponses:


421

Copiez plusieurs fichiers de la télécommande vers la locale:

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

Copiez plusieurs fichiers du local vers le distant:

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

Copiez plusieurs fichiers de télécommande à télécommande:

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

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


5
La première commande a omis une fin "." Et '{a, b, c}' est égal à \ {a, b, c \}.
duleshi

11
Je pense que OP essaie de copier plusieurs fichiers dans plusieurs dossiers locaux vers plusieurs dossiers distants, ces exemples ne feront pas le travail, car ils scapperont tous les fichiers ~ou ./seulement.
aesede

20
Attention: pas d'espace après les virgules dans les accolades. Je viens de passer 10 minutes à essayer de comprendre pourquoi ma commande ne fonctionnait pas et c'était à cause des espaces.
deepak

13
@duleshi {a, b, c} n'est pas exactement égal à \ {a, b, c \} lors de la copie de distant vers local, car le premier requiert un mot de passe pour chaque fichier tandis que le second ne requiert un mot de passe qu'une seule fois.
Marcelo Ventura

15
@MarceloVentura, @duleshi: De plus, j'aimerais ajouter que l'utilisation \{a,b,c\}transférera les fichiers dans une seule connexion / lot (car ils seront développés sur l'hôte distant), tandis que l'utilisation {a,b,c}ouvrira plusieurs connexions et la surcharge est tout à fait visible lors du transfert de nombreux fichiers
omninonsense

140

Du local au serveur:

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

Du serveur au local:

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


6
Cela devrait être la réponse en haut, car le serveur ne demande pas le mot de passe pour chaque fichier :)
motagirl2

Ne fonctionne pas sur le client sur Ubuntu 18 (zsh). Je ne sais pas où cela devrait fonctionner. `` `(venv) ➜ git: (master) ✗ scp root @ 172.29..xxx.yyy:" / usr / local / bin / kubectl /root/.kube/config "/ tmp / root @ 172.29..xxx. mot de passe de yyy: erreur de protocole: le nom de fichier ne correspond pas à la demande `` `
jseguillon

3
@ motagirl2 La première réponse ne demande pas le mot de passe pour chaque fichier tant que vous échappez aux accolades avec la barre oblique inverse. Cette réponse me donne une erreur indiquant que le fichier est introuvable.
Pluton

1
@jseguillon Ajoutez l' -Toption pour supprimer cette erreur.
Rétablir Monica

1
le second fonctionne sur mes machines mais uniquement sans l'option -T
Richard DiSalvo

71

Vous pouvez copier des répertoires entiers en utilisant -rswitch, donc si vous pouvez isoler vos fichiers dans votre propre répertoire, vous pouvez tout copier à la fois.

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

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

donc par exemple

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

Ou s'il y en a peu, vous pouvez utiliser:

scp 1.txt 2.txt 3.log user@remote-server:upload-path

Est-ce que cela fonctionne si ma destination est root et que je fais le répertoire etc comme par exemple: scp -r / backups / etc root @ linuxbox: / où ma source est un répertoire très clairsemé avec des choses comme "hosts" et nginx / sites -disponible etc?
Tomachi

47

Comme Jiri l'a mentionné, vous pouvez utiliser scp -r user@host:/some/remote/path /some/local/pathpour copier des fichiers de manière récursive. Cela suppose qu'il existe un seul répertoire contenant tous les fichiers que vous souhaitez transférer (et rien d'autre).

Cependant, SFTP fournit une alternative si vous souhaitez transférer des fichiers à partir de plusieurs répertoires différents et que les destinations ne sont pas identiques:

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

Cela utilise la syntaxe "ici doc" pour définir une séquence de commandes d'entrée SFTP. Vous pouvez également placer les commandes SFTP dans un fichier texte et exécutersftp user@host -b batchFile.txt


3
C'est la seule réponse qui répond réellement à la question. Merci. J'ai scpcherché sur Google et analysé le manuel pendant trop longtemps pour trouver cette fonctionnalité, et je suppose que scp ne l'a pas.
sudo

1
Cela semble être la meilleure réponse, la plus flexible. Remarque: j'ai été déclenché jusqu'à ce que je réalise que je devais utiliser un chemin complet comme /home/vagrant/Code/au lieu de ~/Code/.
Ryan

Ceci est la meilleure réponse, n'oubliez pas d'ajouter - rdes répertoires
Chris_Rands

25

Les réponses avec {file1,file2,file3}ne fonctionnent qu'avec bash (à distance ou localement)

La vraie façon est:

scp user@remote:'/path1/file1 /path2/file2 /path3/file3' /localPath

1
Fantastique! J'utilise parfois des obus non bash et cela aide énormément. Pas seulement de la vraie façon, mais de la bonne façon.
Paul B.

1
Globbing avec des {…, …, …}œuvres dans de nombreux obus, pas seulement dans Bash. Cependant, cela fonctionne dans n'importe quel shell, c'est donc clairement mieux.
Piotr Dobrogost

A besoin de plus de devis. Ces chemins peuvent contenir des espaces.
Amit Naidu

1
Et voilà! Je voterais cela plusieurs fois, mais je ne peux le faire qu'une seule fois! Merci Vouze!
André Pacheco

17

Après avoir joué avec scp pendant un certain temps, j'ai trouvé la solution la plus robuste:

(Attention aux guillemets simples et doubles)

Local à distant:

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

De distance au local:

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

Notez que quoi que ce soit après "HOST:" sera envoyé à la télécommande et analysé là-bas. Nous devons donc nous assurer qu'ils ne sont pas traités par le shell local. C'est pourquoi les guillemets simples entrent en jeu. Les guillemets doubles sont utilisés pour gérer les espaces dans les noms de fichiers.

Si les fichiers sont tous dans le même répertoire, nous pouvons utiliser * pour les faire correspondre tous, tels que

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

Comparé à l'utilisation de la syntaxe "{}" qui n'est supportée que par certains shells, celle-ci est universelle


Merci d'avoir aidé avec les espaces dans les noms de fichiers. J'utilisais l'approche {}, j'ai donc dû également leur échapper avec \ après la citation.
Noumenon

3
Dans le cas où vous souhaitez utiliser le caractère tilde (~) pour votre répertoire personnel dans les chemins. Notez comment les ~ et / doivent être en dehors des guillemets. `` `scp -r robwaa@192.168.1.101: '~ /" bin / set-vpn-kill-switch "~ /" bin / flush-iptables "' ~ /" "` `
Rob Waa

La {}syntaxe facilite la copie de plusieurs fichiers à partir du même répertoire, y a-t-il un moyen de le faire de scp -rsorte qu'il "FILE1" "FILE2"puisse s'agir de chemins relatifs et non de chemins absolus vers les fichiers?
dtasev

15

Le moyen le plus simple est

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

Ainsi, la liste {..} peut inclure des répertoires (A, B et C voici des répertoires; "1.txt" et "2.txt" sont des noms de fichier dans ces répertoires).

Bien qu'il copierait tous ces quatre fichiers dans un répertoire local - je ne sais pas si c'est ce que vous vouliez.

Dans le cas ci-dessus, vous finirez par copier les fichiers distants A / 1.txt, A / 2.txt, B / 3.txt et C / 4.txt dans un seul répertoire local, avec les noms de fichier ./1.txt, ./2.txt, ./3.txt et ./4.txt


Cela ne remplacerait-il pas le contenu de A / 1.txt par le contenu de B / 1.txt sur la machine locale?
Yves Dorfsman

bon point .. exemple ajusté (alors maintenant il ne serait pas écrasé) et description ajoutée. Merci.
Tagar

Les extensions d'accolade comme celle-ci sont une fonctionnalité Bash, et ne sont pas portables, par exemple POSIX sh.
tripleee

1
@tripleee, merci. ce n'est peut-être pas posix, mais cela ne fonctionne pas seulement en bash. J'utilise ksh tout le temps et ça marche aussi.
Tagar

1
Vous pouvez également mélanger les répertoires et les fichiers en faisant:local$ scp -r remote:{A/1.txt,A/2.txt,B/3.txt,C/4.txt,D,F} ./
donhector

13

Problème : copie de plusieurs répertoires du serveur distant vers la machine locale à l'aide d'une seule commande SCP et conservation de chaque répertoire tel qu'il se trouve sur le serveur distant.

Solution : SCP peut le faire facilement. Cela résout le problème ennuyeux de la saisie du mot de passe plusieurs fois lors de l'utilisation de SCP avec plusieurs dossiers. Par conséquent, cela fait également gagner beaucoup de temps!

par exemple

# 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: Motivé par cette excellente réponse: scp ou sftp copier plusieurs fichiers avec une seule commande


Sur la base des commentaires, cela fonctionne également très bien dans Git Bash sur Windows


3
PS n'ajoute pas d'espaces entre les éléments. ie \ {t1, t2, t3 \} ------> J'ai perdu dix minutes ici ... lol
kenberkeley

1
C'est la meilleure réponse car lorsque vous échappez aux accolades, elle sera interprétée comme une seule commande par et ne demandera pas le mot de passe pour chaque transfert
Amaynut

@Amaynut oui, exactement! Cela économise certainement beaucoup de temps et d'efforts :)
kmario23

12

Copiez plusieurs répertoires:

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

la question était de savoir comment copier d'un répertoire distant vers un répertoire local, et non l'inverse.
Tagar

5

Vous pouvez procéder de cette façon:

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

Cela téléchargera tous les noms de fichiers répertoriés dans le répertoire local sur lequel vous vous trouvez.

Assurez-vous de ne pas mettre d'espaces entre chaque nom de fichier, utilisez uniquement une virgule ,.


1
C'est bien quand l'extension est la même. Il peut être écrit comme /path/to/files/\\{file1.ext,file2.ext,file3.ext\\}si les fichiers avaient des extensions différentes. Remarque pour les personnes PowerShell (maintenant que MS a rejoint le groupe), vous devez utiliser `pour vous échapper à la place:/path/to/files/`{file1.ext,file2.ext,file3.ext`}
dtasev

3

REMARQUE: Je m'excuse à l'avance de ne répondre qu'à une partie de la question ci-dessus. Cependant, j'ai trouvé ces commandes utiles pour mes besoins Unix actuels.

Téléchargement de fichiers spécifiques d'une machine locale vers une machine distante:

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

Téléchargement d'un répertoire entier d'une machine locale vers une machine distante:

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

Téléchargement d'un répertoire entier d'une machine distante vers une machine locale:

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


3

Dans mon cas, je ne peux utiliser que la commande sftp.
J'ai donc dû utiliser un fichier batch avec sftp. J'ai créé un script tel que le suivant. Cela suppose que vous travaillez dans le répertoire / tmp et que vous souhaitez placer les fichiers dans le système destdir_on_remote_system sur le système distant. Cela ne fonctionne également qu'avec une connexion non interactive. Vous devez configurer des clés publiques / privées pour pouvoir vous connecter sans entrer de mot de passe. Changez au besoin.

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

votre commande fonctionne parfaitement mais, je veux aussi changer le nom du fichier lors de l'envoi local vers distant. J'ai écrit une commande: - sshpass -p mot de passe scp /path/to/file.txt root @ hostname: /path/newfile.txt

Mais cela donne une erreur que /path/newfile.txt: Aucun fichier ou répertoire de ce type n'a été trouvé plz m'aider dans cette situation


Assurez-vous que le répertoire distant hostname:/path/existe réellement et qu'il est accessible.
Amit Naidu

1

scp utilise ssh pour le transfert de données avec la même authentification et offre la même sécurité que ssh.

Une meilleure pratique consiste ici à implémenter "CLÉS SSH ET AUTHENTIFICATION DE CLÉS PUBLIQUES". Avec cela, vous pouvez écrire vos scripts sans vous soucier de l'authentification. Aussi simple que cela.

Voir QU'EST - CE QUE SSH-KEYGEN


1

Dans le cas spécifique où tous les fichiers ont la même extension mais avec un suffixe différent (par exemple, le nombre de fichiers journaux), vous utilisez ce qui suit:

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

Cela copiera tous les fichiers nommés some_log_file du dossier donné dans la télécommande, c'est-à-dire some_log_file.1, some_log_file.2, some_log_file.3 ....


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

merci, mais ce n'est qu'un exemple, et le nom du fichier ou du répertoire est plus complexe. Mais j'en ai une liste.
user987654

Pouvez-vous les décrire par une expression régulière?
unxnut

Est-il possible de conserver la même structure de répertoires dans le répertoire cible en utilisant l'expression régulière?
user987654

1
Oui, vous devriez pouvoir le faire avec l' -roption to scp. Et vous pouvez conserver d'autres attributs (comme l'horodatage) avec l' -poption.
unxnut
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.