Preciso executar um script remoto usando ssh
via Ruby
( net / ssh ) para copiar recursivamente uma pasta e excluir uma subpasta. Estou procurando a maneira mais rápida de fazê-lo, rsync
não é bom. Além disso, eu entendo que ssh
usa sh
e não bash
.
No bash eu faço:
cp -r srcdir/!(subdir) dstdir
e funciona bem. No entanto, quando inicio o script via ssh
, recebo o erro
sh: 1: Syntax error: "(" unexpected
porque está usando sh
.
Eu verifiquei a sh
página de manual, mas não há opção para excluir arquivos.
É minha suposição de ssh
usar o sh
correto? Alguma sugestão alternativa?
EDIT 1:
Caso seja útil, a saída de sudo cat /etc/shells
é a seguinte:
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/tmux
/usr/bin/screen
EDIT 2:
OK. Portanto, o bash está disponível e esse não parece ser o problema. Eu verifiquei que o ssh está realmente usando bash
. O problema parece estar relacionado ao escape de parênteses ou ponto de exclamação. Eu tentei executar o comando a partir do shell (macos) e este é o 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'
Dessa forma, recebo um erro diferente
cp: cannot stat '/home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!(constant)': No such file or directory
EDIT 3:
Com base nos comentários, mudei meu comando adicionandoextglob
Se eu usar
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'
Eu recebo o seguinte erro:
cp: cannot stat '/home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!(constant)': No such file or directory
Se eu não escapar dos parênteses, recebo
bash: -c: line 0: syntax error near unexpected token `('
ssh
(wellsshd
) usa o shell de login do usuário remoto. Poderia ser qualquer coisa.Respostas:
O SSH executa seu shell de login no sistema remoto, seja o que for. Mas
!(foo)
requershopt -s extglob
, o que você pode não ter definido no controle remoto.Tente isso para verificar se o SSH executa o Bash no lado remoto:
Se isso imprimir alguma coisa, mas os scripts de inicialização não estiverem configurados
extglob
, você poderá fazê-lo manualmente no comando passado parassh
:extglob
afeta a análise da linha de comando e só entra em vigor após uma nova linha; portanto, temos que colocar uma nova linha literal, um ponto e vírgula não é suficiente.Além disso, se você escapar do parêntese com barras invertidas, elas perderão suas propriedades especiais, como qualquer outro caractere glob. Não é isso que você deseja fazer neste caso.
fonte
Não sei por que você acha que o rsync seria lento. A velocidade de uma cópia é determinada principalmente pela velocidade do disco. O Rsync tem muitas opções para especificar o que você deseja incluir e excluir, por isso oferece um controle muito melhor do que o shell globbing.
Como o manual do bash afirma, o
!(patter)
somente é reconhecido no bash seextglob
estiver definido. No seu exemplo você não definiuextglob
. Além disso, umbash
iniciado comosh
ainda estábash
, mas desativará algumas extensões para compatibilidade.O servidor SSH começará shell de login do usuário, conforme especificado no
/etc/passwd
. Você pode alterar o shell ou usá-lo para iniciar outro shell que atenda melhor às suas necessidades.fonte
time
.time cp -r mesh/!(constant) N
-> 1.04s reais etime rsync -a mesh/ N --exclude=constant
-> 1.8s reaisAlgumas notas primeiro:
sh
a interpretar a linha de comando enviada pelo cliente, executa o shell de login do usuário no host remoto, comothat-shell -c <the-string-provided-by-the-client>
. O shell de login do usuário remoto pode ser qualquer coisa. Tenha em mente que algumas conchas gostatcsh
,fish
ourc
tem sintaxe muito diferente da desh
.ssh host cmd arg1 'arg 2'
ondecmd
,arg1
earg 2
são três argumentos passados parassh
,ssh
concatena esses argumentos com espaços e realmente envia acmd arg1 arg 2
string parasshd
, eo shell remoto iria dividir isso emcmd
,arg1
,arg
e2
.!(subdir)
é um operador glob (umksh
operador glob também suportado porzsh -o kshglob
ebash -O extglob
). Como todos os globs, ele exclui arquivos ocultos, portanto, cuidado, pode haver outros arquivos que ele exclui.Aqui, para evitar o problema de descobrir a sintaxe correta para o shell remoto, você pode realmente dizer a esse outro shell para iniciar o shell desejado e alimentá-lo com o código via stdin (uma das opções listadas em Como executar um simples arbitrário comando sobre ssh sem conhecer o shell de login do usuário remoto? )
bash -O extglob -O dotglob
é uma linha de comando que é entendido o mesmo por todas as grandes conchas, incluindo Bourne-like queridos, csh, rc, peixe ... O acima iria trabalhar enquantobash
está instalado e está em do usuário$PATH
(padrão$PATH
, possivelmente modificadas pelo utilizador do shell de login como~/.zshenv
forzsh
,~/.cshrc
forcsh
,~/.bashrc
forbash
).POSIXly (embora, na prática, você possa achar que mais sistemas têm um
bash
comando do que umpax
comando), você pode:-s
aplica substituições aos caminhos que estão sendo transferidos. Quando essa substituição se expande para nada, o arquivo é excluído. O problema é que as substituições também se aplicam ao destino dos links simbólicos. É por isso que usamos.//.
acima para reduzir a probabilidade de um link simbólico ser afetado.fonte
Eu não acho que
ssh
é limitado a usarsh
. Depende do que está instalado no sistema de destino, como o usuário está configurado e em quais shells são permitidos/etc/shells
.Você considerou o
chsh
comando?fonte
Se você deseja fazer isso de maneira rápida, pode ver
rsync
com um algoritmo de criptografia diferente. Isso lhe dá a opção de excluir facilmente etc., sem sacrificar a velocidade.rsync -aHAXxv --numeric-ids --progress -e "ssh -T -c arcfour -o Compression=no -x" user@<source>:<source_dir> <dest_dir>
juntamente com a adição da
arcfour
criptografia à linha que começa comCiphers
in/etc/ssh/ssh_config
, se ainda não estiver ativada, fornece uma velocidade aceitável.AVISO: A
arcfour
criptografia é insegura . NÃO execute isso em canais inseguros. Se você estiver preocupado com o acesso ao servidor a partir de canais inseguros usandoarcfour
criptografia, altereetc/ssh/ssh_config
com uma parte específica do host para o host de origem - Crie umaHost
seção no ssh_config para o host de origem, useCiphers arcfour
-o para espelhar a-c
opção acima , que restringe aarcfour
criptografia apenas a este host.Para detalhes, consulte as
ssh_config
páginas de manual.No entanto, se suas CPUs suportam o conjunto de instruções AES-NI, tente mudar para [email protected] (sim, esse é o nome da cifra, incluindo o @ stuff), que usará o incrivelmente rápido (com AES-NI) AES128 -GCM.
Portanto, com uma CPU compatível com AES-NI, mude
"ssh -T -c arcfour -o Compression=no -x"
para"ssh -T -c [email protected] -o Compression=no -x"
para resultados mais seguros.Explicação
rsync
-z
, é muito mais lento)a
: modo de arquivamento - rescursivo, preserva o proprietário, preserva permissões, preserva os tempos de modificação, preserva o grupo, copia links simbólicos como links simbólicos, preserva arquivos do dispositivo.H
: preserva links físicosA
: preserva ACLsX
: preserva atributos estendidosx
: não cruze os limites do sistema de arquivosv
: aumentar a verbosidade--numeric-ds
: não mapeie valores uid / gid por nome de usuário / grupo--delete
: exclua arquivos estranhos dos diretórios de destino (limpeza diferencial durante a sincronização)--progress
: mostra o progresso durante a transferênciassh
T
: desative o pseudo-tty para diminuir a carga da CPU no destino.c arcfour
: use a criptografia SSH mais fraca, mas mais rápida. É necessário especificar "Cifras arcfour" em sshd_config no destino.o Compression=no
: Desative a compactação SSH.x
: desativa o encaminhamento do X se estiver ativado por padrão.A carne está nas
ssh
opções - se você usar apenasrsync -av
a-e ssh -T -c arcfour -o Compression=no -x"
peça, poderá obter essas velocidades também.Comparação:
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
Fontes :
https://gist.github.com/KartikTalwar/4393116
http://nz2nz.blogspot.com/2018/05/rsync-scp-sftp-speed-test.html
fonte
cp -r
no sistema remoto, portanto a criptografia usada pela conexão SSH não é realmente relevante. De qualquer forma,arcfour
é considerado um pouco quebrado e o OpenSSH o desativa junto com outros no servidor por padrão desde a versão 6.7 (06-10-2014) . De qualquer forma,ssh -o Ciphers='aes128-ctr'
me fornece cerca de 90 MB / s, o que deve ser rápido o suficiente em um link de 1 Gbit / s.De acordo com meus cálculos, a cópia completa mais rápida está sempre usando 'tar' (aqui assumindo o GNU
tar
ou compatível).E
tar
possui inúmeras opções para manipular atributos, permissões e seleção / exclusão de arquivos. Por exemplo, o comando acima exclui a subpasta de nível superior chamada .thumbcache durante a cópia.fonte
--exclude=.thumbcache
exclui todos os.thumbcache
arquivos, não apenas o de nível superior. Com o GNUtar
(nãobsdtar
), você pode usar--exclude=./.thumbcache
para excluir apenas o.thumbcache
arquivo de nível superior .