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?

user987654
la source
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 [email protected]:'/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 [email protected]:/some/remote/directory/\{a,b,c\} ./

Copiez plusieurs fichiers du local vers le distant:

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

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

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

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

ios.id0
la source
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 [email protected]:~/pathtoupload

Du serveur au local:

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

Gtr_py
la source
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 [email protected]:/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
Jiri Kremser
la source
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

alev
la source
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
Vouze
la source
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

éosphorox
la source
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 [email protected]: '~ /" 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

Tagar
la source
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 [email protected]:/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

kmario23
la source
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 [email protected]:~/
yuliskov
la source
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 ,.

J_rad
la source
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 [email protected]:Folder1/DestinationFolderForFiles/

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

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

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

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

fat43r 80ard
la source
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
dminear
la source
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

Reshmi KC
la source
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

août
la source
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 [email protected]:/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 ....

Guy Avraham
la source
-1
scp remote:"[A-C]/[12].txt" local:
unnut
la source
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