J'ai besoin d'exécuter un script distant en utilisant ssh
via Ruby
( net / ssh ) pour copier récursivement un dossier et exclure un sous-dossier. Je cherche le moyen le plus rapide de le faire donc ce rsync
n'est pas bon. Aussi, je comprends que cela ssh
utilise sh
et non bash
.
En bash je fais:
cp -r srcdir/!(subdir) dstdir
et ça marche bien. Cependant, lorsque je lance le script via, ssh
je reçois l'erreur
sh: 1: Syntax error: "(" unexpected
car il utilise sh
.
J'ai vérifié la sh
page de manuel, mais il n'y a pas d'option pour exclure des fichiers.
Est-ce ma supposition d' ssh
utiliser sh
correctement? Une autre suggestion?
EDIT 1:
Si cela est utile, la sortie de sudo cat /etc/shells
est la suivante:
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/tmux
/usr/bin/screen
EDIT 2:
OK. Alors bash, il est disponible et cela ne semble pas être le problème. J'ai vérifié que le ssh utilise réellement bash
. Le problème semble être lié à la fuite de parenthèses ou d'exclamation. J'ai essayé d'exécuter la commande à partir du shell (macos) et voici la commande réelle:
ssh -i .ssh/key.pem ubuntu@X.X.X.X 'mkdir /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N; cp -r /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!\(constant\) /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N; ln -s /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/constant /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N/constant'
De cette façon, je reçois une erreur différente
cp: cannot stat '/home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!(constant)': No such file or directory
EDIT 3:
Sur la base des commentaires, j'ai changé ma commande en ajoutantextglob
Si j'utilise
ssh -i .ssh/key.pem ubuntu@X.X.X.X 'shopt -s extglob; mkdir /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N; cp -r /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!\(constant\) /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N; ln -s /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/constant /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N/constant'
Je reçois l'erreur suivante:
cp: cannot stat '/home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!(constant)': No such file or directory
Si je n'échappe pas à la parenthèse, je reçois
bash: -c: line 0: syntax error near unexpected token `('
ssh
(enfinsshd
) utilise le shell de connexion de l'utilisateur distant. Ça pourrait être n'importe quoi.Réponses:
SSH exécute votre shell de connexion sur le système distant, quel qu'il soit. Mais
!(foo)
nécessiteshopt -s extglob
, que vous n'avez peut-être pas réglé sur la télécommande.Essayez ceci pour voir si SSH exécute Bash du côté distant:
Si cela imprime quelque chose, mais que vos scripts de démarrage ne sont pas définis
extglob
, vous pouvez le faire à la main à l'aide de la commande passée àssh
:extglob
affecte l'analyse de la ligne de commande, et ne prend effet qu'après une nouvelle ligne, nous devons donc y mettre une nouvelle ligne littérale, un point-virgule ne suffit pas.Ce n'est pas non plus que si vous échappez à la parenthèse avec des barres obliques inverses, ils perdent leurs propriétés spéciales, comme tous les autres caractères globaux. Ce n'est pas ce que vous voulez faire dans ce cas.
la source
Je ne sais pas pourquoi vous pensez que rsync serait lent. La vitesse d'une copie est principalement déterminée par la vitesse du disque. Rsync a de nombreuses options pour spécifier ce que vous voulez inclure et exclure, il vous donne donc un bien meilleur contrôle que la globalisation du shell.
Comme l'indique le manuel bash, le
!(patter)
est uniquement reconnu dans bash siextglob
est défini. Dans votre exemple, vous n'avez pas définiextglob
. De plus, un abash
commencé telsh
quelbash
, mais désactivera certaines extensions pour des raisons de compatibilité.Le serveur SSH démarre le shell de connexion de l'utilisateur, comme spécifié dans
/etc/passwd
. Vous pouvez soit changer le shell, soit utiliser ce shell pour démarrer un autre shell qui correspond mieux à vos besoins.la source
time
.time cp -r mesh/!(constant) N
-> réel 1,04 ettime rsync -a mesh/ N --exclude=constant
-> réel 1,8Quelques notes d'abord:
sh
à interpréter la ligne de commande envoyée par le client, il exécute le shell de connexion de l'utilisateur sur l'hôte distant, commethat-shell -c <the-string-provided-by-the-client>
. Le shell de connexion de l'utilisateur distant peut être n'importe quoi. Gardez à l' esprit que certains coquillages commetcsh
,fish
ourc
une syntaxe très différente de celle desh
.ssh host cmd arg1 'arg 2'
oùcmd
,arg1
etarg 2
sont trois arguments transmisssh
,ssh
concatène ces arguments avec des espaces et envoie en fait lacmd arg1 arg 2
chaîne àsshd
et shell distant fendrait que danscmd
,arg1
,arg
et2
.!(subdir)
est un opérateur glob (unksh
opérateur glob également pris en charge parzsh -o kshglob
etbash -O extglob
). Comme tous les globes, il exclut les fichiers cachés, donc méfiez-vous qu'il peut y avoir d'autres fichiers qu'il exclut.Ici, pour éviter le problème de trouver la bonne syntaxe pour le shell distant, vous pouvez réellement dire à cet autre shell de démarrer le shell que vous voulez et de lui donner le code via stdin (l'une des options répertoriées dans Comment exécuter un simple arbitraire commande sur ssh sans connaître le shell de connexion de l'utilisateur distant? )
bash -O extglob -O dotglob
est une ligne de commande qui est comprise de la même manière par tous les principaux shells, y compris ceux de type Bourne, csh, rc, fish ... Ce qui précède fonctionnerait tant qu'ilbash
est installé et est dans l'utilisateur$PATH
(par défaut$PATH
, éventuellement modifié par l'utilisateur) login shell comme avec~/.zshenv
forzsh
,~/.cshrc
forcsh
,~/.bashrc
forbash
).POSIXly (bien qu'en pratique, vous pouvez trouver que plus de systèmes ont une
bash
commande qu'unepax
commande), vous pouvez faire:-s
applique des substitutions aux chemins transférés. Lorsque cette substitution se développe à rien, le fichier est exclu. Le problème est que les substitutions s'appliquent également à la cible des liens symboliques. C'est pourquoi nous utilisons.//.
ci-dessus pour réduire la probabilité qu'un lien symbolique soit affecté.la source
Je ne pense pas que ce
ssh
soit limité à l'utilisationsh
. Cela dépend plutôt de ce qui est installé sur le système cible, de la configuration de l'utilisateur et des shells autorisés/etc/shells
.Avez-vous pensé à la
chsh
commande?la source
Si vous voulez le faire rapidement, vous pouvez regarder
rsync
avec un algorithme de cryptage différent. Cela vous donne la possibilité d'exclure facilement etc., sans sacrifier beaucoup de vitesse.rsync -aHAXxv --numeric-ids --progress -e "ssh -T -c arcfour -o Compression=no -x" user@<source>:<source_dir> <dest_dir>
avec l'ajout du
arcfour
cryptage à la ligne commençant parCiphers
in/etc/ssh/ssh_config
, s'il n'est pas déjà activé, vous donne une vitesse acceptable.AVERTISSEMENT: le
arcfour
cryptage n'est pas sécurisé . Ne l'exécutez PAS sur des canaux non sécurisés. Si vous êtes préoccupé par l'accès au serveur à partir de canaux non sécurisés à l'aide duarcfour
chiffrement, modifiez leetc/ssh/ssh_config
avec une partie spécifique à l'hôte pour votre hôte source - Créez uneHost
section dans votre ssh_config pour votre hôte source, vous pouvez l'utiliserCiphers arcfour
pour refléter le-c
commutateur ci-dessus , qui restreint learcfour
chiffrement à cet hôte uniquement.Pour plus de détails, reportez-vous aux
ssh_config
pages de manuel.Cependant, si vos processeurs prennent en charge le jeu d'instructions AES-NI, essayez de passer à [email protected] (oui, c'est le nom du chiffrement, y compris les éléments @), qui utilisera le AES128 extrêmement rapide (avec AES-NI) -GCM.
Donc, avec un processeur prenant en charge AES-NI, passez
"ssh -T -c arcfour -o Compression=no -x"
à"ssh -T -c [email protected] -o Compression=no -x"
pour des résultats plus sécurisés.Explication
rsync
-z
, c'est beaucoup plus lent)a
: mode archive - rescursif, préserve le propriétaire, préserve les autorisations, préserve les temps de modification, préserve le groupe, copie les liens symboliques en tant que liens symboliques, préserve les fichiers de périphérique.H
: conserve les liens physiquesA
: conserve les ACLX
: conserve les attributs étendusx
: ne franchissez pas les limites du système de fichiersv
: augmenter la verbosité--numeric-ds
: ne mappez pas les valeurs uid / gid par nom d'utilisateur / groupe--delete
: supprimez les fichiers superflus des répertoires dest (nettoyage différentiel pendant la synchronisation)--progress
: montrer les progrès pendant le transfertssh
T
: désactiver le pseudo-tty pour diminuer la charge du processeur sur la destination.c arcfour
: utilisez le cryptage SSH le plus faible mais le plus rapide. Doit spécifier "Ciphers arcfour" dans sshd_config sur la destination.o Compression=no
: Désactivez la compression SSH.x
: désactiver le transfert X s'il est activé par défaut.Le boeuf est dans les
ssh
options - si vous utilisez simplementrsync -av
la-e ssh -T -c arcfour -o Compression=no -x"
pièce, vous pouvez également obtenir ces vitesses.Comparaison:
rsync -az
scp -Cr
rsync -a
sftp
scp -r
sftp -R 128 -B 65536
rsync -a -P -e "ssh -T -c arcfour -o Compression=no -x"
scp -r -c arcfour
sftp -oCiphers=arcfour
Sources :
https://gist.github.com/KartikTalwar/4393116
http://nz2nz.blogspot.com/2018/05/rsync-scp-sftp-speed-test.html
la source
cp -r
dans le système distant, donc le cryptage utilisé par la connexion SSH n'est pas vraiment pertinent. Dans tous les casarcfour
est considéré comme plutôt cassé et OpenSSH le désactive avec d'autres sur le serveur par défaut depuis la version 6.7 (2014-10-06) . Dans tous les cas, celassh -o Ciphers='aes128-ctr'
me donne environ 90 Mo / s, ce qui devrait être assez rapide sur une liaison à 1 Gbit / s.Selon mes calculs, la copie complète la plus rapide utilise toujours 'tar' (en supposant ici GNU
tar
ou compatible).Et
tar
dispose d'une tonne d'options pour manipuler les attributs, les autorisations et la sélection / exclusion de fichiers. Par exemple, la commande ci-dessus exclut le sous-dossier de niveau supérieur appelé .thumbcache lors de la copie.la source
--exclude=.thumbcache
exclut tous les.thumbcache
fichiers, pas seulement celui du niveau supérieur. Avec GNUtar
(pasbsdtar
), vous pouvez utiliser--exclude=./.thumbcache
pour exclure uniquement le.thumbcache
fichier de niveau supérieur .