Eu tenho que executar um script de shell (windows / Linux) em uma máquina remota.
Eu tenho o SSH configurado nas máquinas A e B. Meu script está na máquina A, que executará parte do meu código em uma máquina remota, máquina B.
Os computadores locais e remotos podem ser do sistema Windows ou Unix.
Existe uma maneira de executar isso usando plink / ssh?
shell
ssh
sysadmin
remote-execution
alpha_989
fonte
fonte
Respostas:
Se a Máquina A for uma caixa do Windows, você poderá usar o Plink (parte do PuTTY ) com o parâmetro -m, e ele executará o script local no servidor remoto.
Se a Máquina A for um sistema baseado em Unix, você poderá usar:
Você não precisa copiar o script para o servidor remoto para executá-lo.
fonte
-s
opção? Essa página de manual me leva a acreditar que processará a entrada padrão quando terminar as opções de processamento,-s
usadas ou não.sudo
, executessh root@MachineB 'echo "rootpass" | sudo -Sv && bash -s' < local_script.sh
.HISTCONTROL=ignoreboth or ignorespace
para torná-lo trabalho)ssh root@MachineB ARG1="arg1" ARG2="arg2" 'bash -s' < local_script.sh
créditos vão totalmente para a resposta @chubbsondubs 'abaixo.Esta é uma pergunta antiga e a resposta de Jason funciona bem, mas eu gostaria de acrescentar:
Isso também pode ser usado com su e comandos que requerem entrada do usuário. (observe o
'
heredoc escapado)Edit: Como esta resposta continua recebendo bits de tráfego, eu adicionaria ainda mais informações a esse maravilhoso uso do heredoc:
Você pode aninhar comandos com esta sintaxe e é a única maneira que o aninhamento parece funcionar (de maneira sã)
Você pode realmente ter uma conversa com alguns serviços como telnet, ftp, etc.
Edit: Acabei de descobrir que você pode recuar o interior com abas se você usar
<<-END
!(Eu acho que isso deve funcionar)
Veja também http://tldp.org/LDP/abs/html/here-docs.html
fonte
<<'ENDSSH'
), as seqüências não serão expandidas, as variáveis não serão avaliadas. Você também pode usar<<ENDSSH
ou<<"ENDSSH"
se desejar expansão.Expect
pode ser usado quando você precisar automatizar comandos interativos como FTP.Pseudo-terminal will not be allocated because stdin is not a terminal.
mensagem. É preciso usar ssh com-t -t
parâmetros para evitar isso. Veja este segmento no SOAlém disso, não esqueça de escapar das variáveis se quiser buscá-las no host de destino.
Isso me chamou a atenção no passado.
Por exemplo:
imprime / casa / usuário2
enquanto
imprime / casa / usuário
Outro exemplo:
imprime "olá" corretamente.
fonte
ssh user2@host 'bash -s' echo $HOME /home/user2 exit
for
loops em execução nassh
sessão, a variável loop não deve ser escapada.ssh user2@host2 'echo hello world' | awk '{ print $1 }'
executar o script Awk localmente. Se o comando remoto produzir uma imensa quantidade de saída, você evita copiar tudo de volta para o servidor local, é claro. Aliás, aspas simples ao redor do comando remoto evitam a necessidade de escape.Esta é uma extensão da resposta do YarekT para combinar comandos remotos em linha com a passagem de variáveis ENV da máquina local para o host remoto, para que você possa parametrizar seus scripts no lado remoto:
Achei isso extremamente útil, mantendo tudo em um script, para que seja muito legível e fácil de manter.
Por que isso funciona? O ssh suporta a seguinte sintaxe:
No bash, podemos especificar variáveis de ambiente a serem definidas antes da execução de um comando em uma única linha, como segue:
Isso facilita a definição de variáveis antes da execução de um comando. Nesse caso, echo é nosso comando que estamos executando. Tudo antes do eco define variáveis de ambiente.
Então, combinamos esses dois recursos e a resposta do YarekT para obter:
Nesse caso, estamos configurando ARG1 e ARG2 para valores locais. Enviando tudo após o usuário @ host como o comando remote_com. Quando a máquina remota executa o comando ARG1 e ARG2 são definidos os valores locais, graças à avaliação da linha de comando local, que define variáveis de ambiente no servidor remoto, e executa o comando bash -s usando essas variáveis. Voila.
fonte
ssh user@host "ARG1=\"$ARG1\" ARG2=\"$ARG2\"" 'bash -s' <<'ENDSSH'...
-s
é poder aplicar argumentos a scripts originados pelo stdin. Quero dizer, você também pode omitir se não for usá-lo. Se você o usar, não há razão para usar variáveis de ambiente:ssh user@host 'bash -s value1 value2' <<< 'echo "$@"'
Isso solicitará a senha, a menos que você tenha copiado a chave pública do usuário hostA para o arquivo allowed_keys na casa do diretório do usuário .ssh. Isso permitirá autenticação sem senha (se aceito como um método de autenticação na configuração do servidor ssh)
fonte
Comecei a usar o Fabric para operações mais sofisticadas. O Fabric requer Python e algumas outras dependências, mas apenas na máquina cliente. O servidor precisa ser apenas um servidor ssh. Acho que essa ferramenta é muito mais poderosa que os scripts de shell entregues ao SSH e vale a pena o esforço de ser configurada (principalmente se você gosta de programar em Python). O Fabric manipula scripts em execução em vários hosts (ou hosts de determinadas funções), ajuda a facilitar operações idempotentes (como adicionar uma linha a um script de configuração, mas não se já estiver lá) e permite a construção de lógica mais complexa (como o Python idioma pode fornecer).
fonte
Tente correr
ssh user@remote sh ./script.unx
.fonte
fonte
Supondo que você queira fazer isso automaticamente a partir de uma máquina "local", sem fazer login manualmente na máquina "remota", procure uma extensão TCL conhecida como Expect, que foi projetada precisamente para esse tipo de situação. Também forneci um link para um script para efetuar login / interagir via SSH.
https://www.nist.gov/services-resources/software/expect
http://bash.cyberciti.biz/security/expect-ssh-login-script/
fonte
Eu uso este para executar um script de shell em uma máquina remota (testada em / bin / bash):
fonte
altamente recomendado para a origem do arquivo de ambiente (.bashrc / .bashprofile / .profile). antes de executar algo no host remoto, pois as variáveis de ambiente dos hosts de destino e de origem podem ser adiadas.
fonte
se você quiser executar comandos como este
temp=`ls -a` echo $temp
em `` causará erros.O comando abaixo resolverá esse problema
ssh user@host ''' temp=`ls -a` echo $temp '''
fonte
A resposta aqui ( https://stackoverflow.com/a/2732991/4752883 ) funciona muito bem se você estiver tentando executar um script em uma máquina Linux remota usando
plink
orssh
. Funcionará se o script tiver várias linhas ativadaslinux
.** No entanto, se você estiver tentando executar um script em lote localizado em uma
linux/windows
máquina local e sua máquina remota estiverWindows
, ela consistirá em várias linhas usando **plink root@MachineB -m local_script.bat
não vai funcionar.
Somente a primeira linha do script será executada. Esta é provavelmente uma limitação de
plink
.Solução 1:
Para executar um script em lotes com várias linhas (especialmente se for relativamente simples, consistindo em algumas linhas):
Se o script em lote original for o seguinte
você pode combinar as linhas usando o separador "&&" da seguinte maneira no seu
local_script.bat
arquivo: https://stackoverflow.com/a/8055390/4752883 :Após essa alteração, você poderá executar o script conforme indicado aqui por @ JasonR.Coombs: https://stackoverflow.com/a/2732991/4752883 com:
Solução 2:
Se o seu script em lote for relativamente complicado, pode ser melhor usar um script em lote que encapsule o comando plink, bem como a seguir, conforme indicado aqui por @Martin https://stackoverflow.com/a/32196999/4752883 :
fonte
Esse script bash faz ssh em uma máquina remota de destino e executa algum comando na máquina remota; não esqueça de instalar o expect antes de executá-lo (no mac
brew install expect
)fonte
Você pode usar runoverssh :
-s
executa um script local remotamenteSinalizadores úteis:
-g
use uma senha global para todos os hosts (prompt de senha única)-n
use SSH em vez de sshpass, útil para autenticação de chave públicafonte
Primeiro, copie o script para a Máquina B usando scp
Em seguida, basta executar o script
Isso funcionará se você der permissão executável ao script.
fonte