Necesito ejecutar un script remoto usando ssh
via Ruby
( net / ssh ) para copiar recursivamente una carpeta y excluir una subcarpeta. Estoy buscando la forma más rápida de hacerlo, así rsync
que no es bueno. Además, entiendo que los ssh
usos sh
y no bash
.
En bash hago:
cp -r srcdir/!(subdir) dstdir
y funciona bien Sin embargo, cuando inicio el script vía ssh
, recibo el error
sh: 1: Syntax error: "(" unexpected
Debido a que está utilizando sh
.
He revisado la sh
página del manual, pero no hay ninguna opción para excluir archivos.
¿Es mi suposición de ssh
usar sh
correcto? ¿Alguna sugerencia alternativa?
EDITAR 1:
en caso de que sea útil, la salida de sudo cat /etc/shells
es la siguiente:
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/tmux
/usr/bin/screen
EDITAR 2:
OK. Entonces bash está disponible y ese no parece ser el problema. He verificado que el ssh está usando realmente bash
. El problema parece estar relacionado con el escape de paréntesis o signo de exclamación. He intentado ejecutar el comando desde el shell (macos) y este es el comando real:
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 esta manera recibo un error diferente
cp: cannot stat '/home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!(constant)': No such file or directory
EDITAR 3:
Basado en los comentarios, he cambiado mi comando agregandoextglob
Si yo uso
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'
Recibo el siguiente error:
cp: cannot stat '/home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!(constant)': No such file or directory
Si no escapo del paréntesis me sale
bash: -c: line 0: syntax error near unexpected token `('
ssh
(buenosshd
) usa el shell de inicio de sesión del usuario remoto. Podría ser cualquier cosa.Respuestas:
SSH ejecuta su shell de inicio de sesión en el sistema remoto, sea lo que sea. Pero
!(foo)
requiereshopt -s extglob
, que puede que no haya configurado en el control remoto.Pruebe esto para ver si SSH ejecuta Bash en el lado remoto:
Si eso imprime algo, pero sus scripts de inicio no se configuran
extglob
, puede hacerlo a mano en el comando pasado assh
:extglob
afecta el análisis de la línea de comando y solo tiene efecto después de una nueva línea, por lo que tenemos que poner una nueva línea literal allí, un punto y coma no es suficiente.Tampoco es que si escapas del paréntesis con barras invertidas, pierden sus propiedades especiales, como cualquier otro personaje global. Esto no es lo que quieres hacer en este caso.
fuente
No sé por qué piensas que rsync sería lento. La velocidad de una copia está determinada principalmente por la velocidad del disco. Rsync tiene muchas opciones para especificar lo que desea incluir y excluir, por lo que le brinda un control mucho mejor que el bloqueo de shell.
Como dice el manual de bash,
!(patter)
solo se reconoce en bash siextglob
está configurado. En tu ejemplo no lo establecisteextglob
. Además, sebash
inició comosh
todavíabash
, pero deshabilitará algunas extensiones por compatibilidad.El servidor SSH iniciará el shell de inicio de sesión del usuario, como se especifica en
/etc/passwd
. Puede cambiar el shell o usar ese shell para iniciar otro shell que se adapte mejor a sus necesidades.fuente
time
.time cp -r mesh/!(constant) N
-> real 1.04s ytime rsync -a mesh/ N --exclude=constant
-> real 1.8sAlgunas notas primero:
sh
a interpretar la línea de comando enviada por el cliente, ejecuta el shell de inicio de sesión del usuario en el host remoto, comothat-shell -c <the-string-provided-by-the-client>
. El shell de inicio de sesión del usuario remoto podría ser cualquier cosa. Tenga en cuenta que algunas conchas gustaríatcsh
,fish
orc
tienen muy diferentes sintaxis de la desh
.ssh host cmd arg1 'arg 2'
, dondecmd
,arg1
yarg 2
son tres argumentos pasados assh
,ssh
concatena los argumentos con espacios y en realidad envía lacmd arg1 arg 2
cadena asshd
, y el shell remoto se dividiría en quecmd
,arg1
,arg
y2
.!(subdir)
es un operador global (unksh
operador global también soportado porzsh -o kshglob
ybash -O extglob
). Al igual que todos los globs, excluye los archivos ocultos, así que tenga cuidado porque puede haber otros archivos que excluye.Aquí, para evitar el problema de encontrar la sintaxis correcta para el shell remoto, puedes decirle a ese otro shell que inicie el shell que deseas y alimentar el código a través de stdin (una de las opciones enumeradas en Cómo ejecutar un simple arbitrario comando sobre ssh sin conocer el shell de inicio de sesión del usuario remoto? )
bash -O extglob -O dotglob
es una línea de comando que todos los shells principales entienden de la misma manera, incluidos los similares a Bourne, csh, rc, fish ... Lo anterior funcionaría mientrasbash
esté instalado y esté en el usuario$PATH
(predeterminado$PATH
, posiblemente modificado por el usuario) iniciar sesión como con~/.zshenv
forzsh
,~/.cshrc
forcsh
,~/.bashrc
forbash
).POSIXY (aunque en la práctica, puede encontrar que más sistemas tienen un
bash
comando que unpax
comando), puede hacer:-s
aplica sustituciones a las rutas que se transfieren. Cuando esa sustitución se expande a nada, el archivo se excluye. El problema es que las sustituciones también se aplican al objetivo de los enlaces simbólicos. Es por eso que usamos lo.//.
anterior para que sea menos probable que un enlace simbólico se vea afectado.fuente
No creo que
ssh
se limite al usosh
. Más bien depende de lo que esté instalado en el sistema de destino, cómo está configurado el usuario y qué shells están permitidos/etc/shells
.¿Consideraste el
chsh
comando?fuente
Si desea hacerlo de manera rápida, puede mirar
rsync
con un algoritmo de cifrado diferente. Esto le da la opción de excluir fácilmente, etc., a poca velocidad de sacrificio.rsync -aHAXxv --numeric-ids --progress -e "ssh -T -c arcfour -o Compression=no -x" user@<source>:<source_dir> <dest_dir>
junto con agregar el
arcfour
cifrado a la línea que comienzaCiphers
en/etc/ssh/ssh_config
, si no está habilitado, le brinda una velocidad aceptable.ADVERTENCIA: el
arcfour
cifrado es inseguro . NO ejecute esto sobre canales inseguros. Si le preocupa el acceso al servidor desde canales inseguros mediante elarcfour
cifrado, cambie eletc/ssh/ssh_config
con una parte específica del host para su host de origen:Host
cree una sección en su ssh_config para su host de origen, puede usarlaCiphers arcfour
para reflejar el-c
interruptor anterior , que restringe elarcfour
cifrado solo a este host.Para más detalles, consulte las
ssh_config
páginas de manual.Sin embargo, si sus CPU son compatibles con el conjunto de instrucciones AES-NI, intente cambiar a [email protected] (sí, ese es el nombre del cifrado, incluido el @), que utilizará el AES128 increíblemente rápido (con AES-NI) -GCM.
Entonces, con una CPU que admita AES-NI, cambie
"ssh -T -c arcfour -o Compression=no -x"
a"ssh -T -c [email protected] -o Compression=no -x"
para obtener resultados más seguros.Explicación
rsync
-z
, es mucho más lento)a
: modo de archivo: rescursivo, conserva el propietario, conserva los permisos, conserva los tiempos de modificación, conserva el grupo, copia los enlaces simbólicos como enlaces simbólicos, conserva los archivos del dispositivo.H
: conserva los enlaces durosA
: conserva las LCAX
: conserva los atributos extendidosx
: no cruce los límites del sistema de archivosv
: aumentar la verbosidad--numeric-ds
: no asigne valores uid / gid por nombre de usuario / grupo--delete
: elimine archivos extraños de los directorios de destino (limpieza diferencial durante la sincronización)--progress
: muestra el progreso durante la transferenciassh
T
: apague pseudo-tty para disminuir la carga de la CPU en el destino.c arcfour
: use el cifrado SSH más débil pero más rápido. Debe especificar "Ciphers arcfour" en sshd_config en el destino.o Compression=no
: Desactiva la compresión SSH.x
: desactiva el reenvío X si está activado de forma predeterminada.La carne está en las
ssh
opciones: si solo usarsync -av
la-e ssh -T -c arcfour -o Compression=no -x"
parte, también puede obtener estas velocidades.Comparación:
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
Fuentes :
https://gist.github.com/KartikTalwar/4393116
http://nz2nz.blogspot.com/2018/05/rsync-scp-sftp-speed-test.html
fuente
cp -r
dentro del sistema remoto, por lo que el cifrado utilizado por la conexión SSH no es realmente relevante. En cualquier caso,arcfour
se considera bastante roto y OpenSSH lo desactiva junto con otros en el servidor de forma predeterminada desde la versión 6.7 (06/10/2014) . En cualquier caso,ssh -o Ciphers='aes128-ctr'
me da unos 90 MB / s, que deberían ser lo suficientemente rápidos en un enlace de 1 Gbit / s.Según mis cálculos, la copia completa más rápida siempre usa 'tar' (aquí asumiendo GNU
tar
o compatible).Y
tar
tiene un montón de opciones para manipular atributos, permisos y selección / exclusión de archivos. Por ejemplo, el comando anterior excluye la subcarpeta de nivel superior llamada .thumbcache durante la copia.fuente
--exclude=.thumbcache
excluye todos los.thumbcache
archivos, no solo el del nivel superior. Con GNUtar
(nobsdtar
), puede usar--exclude=./.thumbcache
para excluir solo el.thumbcache
archivo de nivel superior .