Scp peut créer un répertoire s’il n’existe pas?


89

Je veux utiliser scppour télécharger des fichiers, mais parfois le répertoire cible peut ne pas exister.

Est-il possible de créer le dossier automatiquement? Si c'est le cas, comment? Si non, quel autre moyen puis-je essayer?

Réponses:


72

C'est l'une des nombreuses choses que l' rsyncon peut faire.

Si vous utilisez une version de rsynclibérée au cours des dernières années, ¹ sa syntaxe de commande de base est similaire à scp: ²

$ rsync -r local-dir remote-machine:path

Cela va copier local-sourceet son contenu $HOME/path/local-dirsur la machine distante, en créant les répertoires nécessaires .³

rsyncIl existe certaines restrictions ici qui peuvent affecter si cela fonctionnera dans votre situation particulière. Cela ne créera pas plusieurs niveaux de répertoires distants manquants, par exemple; il ne créera qu'un niveau manquant sur la télécommande. Vous pouvez facilement contourner cela en faisant précéder la rsynccommande avec quelque chose comme ceci:

$ ssh remote-host 'mkdir -p foo/bar/qux'

Cela créera l' $HOME/foo/bar/quxarbre s'il n'existe pas. Il ne se plaindra pas ou faire quoi que ce soit d' autre mauvais si elle n'existe déjà.

rsynca parfois d'autres comportements surprenants. Fondamentalement, vous lui demandez de comprendre ce que vous vouliez copier, et ses suppositions peuvent ne pas correspondre à vos hypothèses. Essayez et voyez. S'il ne se comporte pas comme prévu et que vous ne voyez pas pourquoi, publiez plus de détails sur les configurations de votre répertoire local et distant et donnez la commande que vous avez essayée.


Notes de bas de page :

  1. Avant la version rsync2.6.0 (1 er janvier 2004), il avait besoin de l’ -e sshindicateur pour qu’il se comporte comme scpil se présentait par défaut avec le protocole RSH obsolète .

  2. scpet rsyncpartager des drapeaux, mais il y a peu de chevauchement.

  3. En utilisant SSHcomme protocole de transfert, rsyncutilise les mêmes valeurs par défaut. Ainsi, tout comme scp, cela supposera qu’un utilisateur porte par défaut le même nom que votre utilisateur local sur la machine distante.


J'utilise Mac OSX. Dois-je installer rsync aussi bien du côté local que du côté distant?
AGamePlayer

rsyncla page de documentation consultée , n'a pas trouvé comment utiliser ssh-key pour se connecter. Je ne souhaite pas utiliser identifiant / mot de passe pour
me

1
@AwQiruiGuo: Mac OS X est livré avec rsync. Et oui, vous avez également besoin rsyncdu côté distant, tout comme avec scp. En ce qui concerne les clés SSH, rsyncutilise SSH en dessous avec la valeur par défaut -e ssh. Par conséquent, si vous avez configuré des clés à utiliser avec scp, elles fonctionneront rsyncégalement.
Warren Young

1
@WarrenYoung -rne fait aucune différence. Le scénario que vous décrivez ne fonctionne que si vous copiez un répertoire et si le répertoire parent cible existe. Donc, rsync foo/ u@h:~/créera le répertoire cible foomais rsync foo/ u@h:~/bar/ne créera pas le répertoire cible bar. Celui-ci ne créera bar/fooque s'il bar/existe. Dans tous les cas, l'OP télécharge des fichiers et même dans les cas où cela fonctionne, cela ne fonctionne que pour des répertoires entiers.
terdon

1
Oui, j'ai aussi joué avec. Il semble que la spécification d'un nom de fichier provoque également son échec. Donc rsync file host:/foo/fileéchoue si foo/n'existe pas mais rsync file host:/foo/crée le répertoire et y place file. Étrange. Quoi qu'il en soit, vous avez tout à fait raison et le scénario de base fonctionne, je vais retirer mon vote négatif.
terdon

35

Si vous copiez un groupe de fichiers, pas vraiment. Si vous copiez un répertoire et tout son contenu, oui. Étant donné cette commande:

$ scp -pr /source/directory user@host:the/target/directory

Si directoryn'existe pas ~/the/targetsur host, il sera créé. Si, toutefois, ~the/targetn'existe pas, vous aurez probablement des problèmes - je ne me souviens pas des résultats exacts de ce cas, mais soyez prêt à scpfaire échouer le projet.


1
scp: /home/madmike/test_bin: No such file or directoryDès que le répertoire cible est manquant, cela se produit sur mon installation. Utilisation de cygwin sur le client et de RHEL 6.9 sur le serveur. Quelle est votre configuration?
MadMike

16

Autant que je sache, scpelle - même ne peut pas faire cela, non. Cependant, vous pouvez simplement sshcréer un répertoire sur la machine cible, puis le copier. Quelque chose comme:

ssh user@host "mkdir -p /target/path/" &&
    scp /path/to/source user@host:/target/path/

Notez que si vous copiez des répertoires entiers, ce qui précède n’est pas nécessaire. Par exemple, pour copier le répertoire ~/foosur l'hôte distant, vous pouvez utiliser l' -rindicateur (récursif):

scp ~/foo/ user@host:~/

Cela créera le répertoire cible ~/foosur l'hôte distant. Cependant, il ne peut pas créer le répertoire parent. scp ~/foo user@host:~/bar/fooéchouera sauf si le répertoire cible barexiste. Dans tous les cas, l' -rindicateur ne vous aidera pas à créer un répertoire cible si vous copiez des fichiers individuels.


3

Oui, vous pouvez. Selon la page de manuel de scp:

homme scp

.....

-r Copier récursivement des répertoires entiers. Notez que scp suit les liens symboliques rencontrés dans le parcours de l’arbre.

....


7
Cela ne créera pas le répertoire parent cible. Il peut copier un répertoire dans un emplacement existant. Donc, scp -r foo/ u@h:~/barcréera bar/foosi la télécommande bar/existe mais échouera si elle n’existe pas.
terdon

1
Cela ne va pas échouer. Il copiera le foocontenu dans le nouveau répertoire /bar. Bien sûr, le nom a été changé, ce qui peut ne pas être ce que souhaite le PO. Si ce que vous voulez, c'est une nouvelle structure d'arborescence créée dans la machine de destination, scple travail ne sera pas effectué. Si ce que vous voulez, c'est de répliquer une structure d'arborescence à partir d'une certaine branche de l'arborescence, cette structure est créée.
YoMismo

6
Oui, mais cela ne fonctionne que si vous copiez des répertoires , pas des fichiers. scp -r file host:~/bar/ne créera pas bar/.
terdon

3

J'utilise la fonction suivante avant de transférer des btrfsinstantanés sur ssh:

check_remote_dir() {
        printf "\ntesting remote directory: '$1' "

        if ssh -p $PORT $ROOT@$REMOTE "[ ! -d $1 ]"; then
                printf "\nCreating: $1 on $ROOT@$REMOTE\n"
                ssh -p $PORT $ROOT@$REMOTE "mkdir -p $1"
        else
                printf "[OK]\n"
        fi
}

Appelez simplement la fonction dans votre script avec:

check_remote_dir /my/remote/path


Je fais à peu près la même chose, mais je dois taper le mot de passe manuellement (pour des raisons de sécurité), je finis donc par le saisir au moins deux fois ...
Stefan Reich

0

Vous pouvez chaîner la commande avec la commande mkdir puis faire référence au dossier que vous avez créé:

mkdir ~/new-folder/ && scp -P 22 <remote/url>:~/new-folder/

3
(1) La question dit «automatiquement». Cela ne semble pas être automatique. (2) Cela ne semble être qu'une variation triviale de la réponse de terdon .
G-Man le

0

Lorsque restreint à scp ou sftp sans ssh disponible (par rssh), il est possible de créer des répertoires en copiant une arborescence de répertoires vide avec rsync, puis en copiant des fichiers.

Voici comment j'ai mis la clé publique ssh sur l'hôte distant lorsque ssh-copy-id ne fonctionne pas et que le répertoire .ssh n'existe pas:

rsync -e 'ssh -p22' -av -f"+ */" -f"- *" ~/.ssh backup@1.2.3.4:~/
scp -P22 ~/.ssh/id_rsa.pub backup@1.2.3.4:~/.ssh/authorized_keys

Il est possible de combiner ces commandes dans un seul rsync en ajoutant un filtre d'inclusion supplémentaire au milieu, si le nom du fichier cible est identique.

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.