Necesito ejecutar un script remoto usando sshvia Ruby( net / ssh ) para copiar recursivamente una carpeta y excluir una subcarpeta. Estoy buscando la forma más rápida de hacerlo, así rsyncque no es bueno. Además, entiendo que los sshusos shy 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 shpágina del manual, pero no hay ninguna opción para excluir archivos.
¿Es mi suposición de sshusar shcorrecto? ¿Alguna sugerencia alternativa?
EDITAR 1:
en caso de que sea útil, la salida de sudo cat /etc/shellses 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:extglobafecta 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 siextglobestá configurado. En tu ejemplo no lo establecisteextglob. Además, sebashinició comoshtodaví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:
sha 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,fishorctienen muy diferentes sintaxis de la desh.ssh host cmd arg1 'arg 2', dondecmd,arg1yarg 2son tres argumentos pasados assh,sshconcatena los argumentos con espacios y en realidad envía lacmd arg1 arg 2cadena asshd, y el shell remoto se dividiría en quecmd,arg1,argy2.!(subdir)es un operador global (unkshoperador global también soportado porzsh -o kshglobybash -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 dotglobes 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 mientrasbashesté instalado y esté en el usuario$PATH(predeterminado$PATH, posiblemente modificado por el usuario) iniciar sesión como con~/.zshenvforzsh,~/.cshrcforcsh,~/.bashrcforbash).POSIXY (aunque en la práctica, puede encontrar que más sistemas tienen un
bashcomando que unpaxcomando), puede hacer:-saplica 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
sshse 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
chshcomando?fuente
Si desea hacerlo de manera rápida, puede mirar
rsynccon 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
arcfourcifrado a la línea que comienzaCiphersen/etc/ssh/ssh_config, si no está habilitado, le brinda una velocidad aceptable.ADVERTENCIA: el
arcfourcifrado es inseguro . NO ejecute esto sobre canales inseguros. Si le preocupa el acceso al servidor desde canales inseguros mediante elarcfourcifrado, cambie eletc/ssh/ssh_configcon una parte específica del host para su host de origen:Hostcree una sección en su ssh_config para su host de origen, puede usarlaCiphers arcfourpara reflejar el-cinterruptor anterior , que restringe elarcfourcifrado solo a este host.Para más detalles, consulte las
ssh_configpá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
sshopciones: si solo usarsync -avla-e ssh -T -c arcfour -o Compression=no -x"parte, también puede obtener estas velocidades.Comparación:
rsync -azscp -Crrsync -asftpscp -rsftp -R 128 -B 65536rsync -a -P -e "ssh -T -c arcfour -o Compression=no -x"scp -r -c arcfoursftp -oCiphers=arcfourFuentes :
https://gist.github.com/KartikTalwar/4393116
http://nz2nz.blogspot.com/2018/05/rsync-scp-sftp-speed-test.html
fuente
cp -rdentro del sistema remoto, por lo que el cifrado utilizado por la conexión SSH no es realmente relevante. En cualquier caso,arcfourse 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
taro compatible).Y
tartiene 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=.thumbcacheexcluye todos los.thumbcachearchivos, no solo el del nivel superior. Con GNUtar(nobsdtar), puede usar--exclude=./.thumbcachepara excluir solo el.thumbcachearchivo de nivel superior .