Eu tenho um script que se conecta a um servidor remoto e verifica se algum pacote está instalado:
ssh root@server 'bash -s' < myscript.sh
myscript.sh:
OUT=`rpm -qa | grep ntpdate`
if [ "$OUT" != "" ] ; then
echo "ntpdate already installed"
else
yum install $1
fi
Este exemplo pode ser simplificado. Aqui está o myscript2.sh
que tem o mesmo problema:
read -p "Package is not installed. Do you want to install it (y/n)?" choise
Meu problema é que o bash não consegue ler minhas respostas interativamente.
Existe uma maneira de executar o script local remotamente sem perder a capacidade de solicitar ao usuário?
Respostas:
Tente algo como isto:
As
-t
forças uma alocação tty,$(<your_script)
lê o arquivo inteiro e nestes casos passa o conteúdo como um argumento parassh
, que será executado pelo shell do usuário remoto.Se o script precisar de parâmetros, passe-os após o script:
Funciona para mim, mas não tenho certeza se é universal.
fonte
your script
, mantendo as vantagens da sintaxe usada na sua resposta? Usandossh -t yourserver "$(<your_script --some_arg)"
apenas resultados embash: --some_arg: command not found
.ssh ... $(<script) script_arg1 script_arg2 ...
Seu problema é que
ssh
inicia um shell não interativo de login na máquina remota. A solução fácil óbvia seria copiar o script para o servidor remoto e executá-lo a partir daí:Se a cópia não é uma opção por qualquer motivo, gostaria de modificar o script para a primeira conexão e verificar se
$1
está instalado, em seguida, reconecte e instalar conforme necessário:fonte
$OUT=$(ssh root@server rpm -qa | grep "$1");
saídas e a segunda conexão levará tanto tempo quanto a primeira. Estou errado?ssh -M foo.example.com sleep 99999999
oussh -M foo.example.com read <somefifo
como mestre e mate-o explicitamente (comkill
ouecho done >somefifo
) quando terminar.Aqui está uma boa explicação .
Então eu adaptei o script para
e isso não funcionou.
então mudei o script para o controle remoto para evitar o redirecionamento local no ssh. (Meus comandos estão em um arquivo chamado f )
Isso funcionou. Aqui está a saída:
Como o @terdon mencionou que a intenção original era executar scripts locais remotamente, a cópia remota pode ser automatizada; este é apenas um exemplo, tudo em uma linha.
fonte
bash -s < script.sh
o OP? Você poderia incluir a explicação na sua resposta em vez de vincular a ela?Eu procurei soluções para esse problema várias vezes no passado, mas nunca encontrei uma totalmente satisfatória. A inserção no ssh perde sua interatividade. Duas conexões (scp / ssh) são mais lentas e seu arquivo temporário pode ficar por aí. E todo o script na linha de comando geralmente acaba escapando do inferno.
Recentemente, descobri que o tamanho do buffer da linha de comando é geralmente bastante grande ('getconf ARG_MAX> 2MB, onde eu olhei). E isso me fez pensar em como eu poderia usar isso e mitigar a questão que escapava.
O resultado é:
ou usando um documento e um gato aqui:
Eu expandi essa ideia para produzir um script de exemplo do BASH totalmente funcional
sshx
que possa executar scripts arbitrários (não apenas o BASH), onde os argumentos também podem ser arquivos de entrada local, através do ssh. Veja aqui .fonte
"
caracteres que precisam ser escapados. E também é restrito a scripts BASH. Minha solução é um caso geral para qualquer conteúdo de script de qualquer linguagem de script instalada. Além disso, no sshx , demonstro ainda a serialização de arquivos de argumentos, o que é bastante bacana.echo "$(cat my_script | base64)" | base64 --decode
parece equivalente (-ish) acat my_script | base64 | base64 --decode
, que parece muito com um não-op.echo "ARG1=$1, USER=$USER, END"
. a)$ ssh host "$(<my_bash)" foo
->ARG1=, USER=user, END foo
. b)$ ssh host bash "<(echo $(cat my_bash|base64) | base64 --decode)" foo
->ARG1=foo, USER=user, END
. Aqui (a) está efetivamente em execução:bash -c $'#!/bin/bash\necho "ARG1=$1, USER=$USER, END" foo'
ou algo semelhante. Observe que o argumento não funciona. Onde (b) está em execução:bash <(echo IyEvY...5EIgo= | base64 --decode) foo
. (2) Eu usei base64 como a codificação de transporte.