Execute vários comandos remotamente usando script bash

Execute vários comandos remotamente usando script bash

Tenho que fazer login em servidores remotos via ssh e ir para a pasta tmp e lá tenho que executar o comando rm. Mas quando estou executando o script abaixo ele vai para o servidor remoto, mas não vai para a pasta temporária e nem executa o comando rm.

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS

Responder1

O único problema real com o seu código é que seu loop não possui doand done, o que causaria erros de sintaxe, e que você está usando icomo variável de loop, mas tente conectar-se a alguma servervariável que pode não estar definida.

Além disso, você está usando catuma substituição de comando sem aspas que égeralmenteuma má idéia se você não tiver certeza de que estará lendo strings sem espaços em branco e caracteres globbing de nome de arquivo (embora os nomes da maioria dos hosts sejam bem comportados nesse aspecto).

Na maioria das vezes é melhor ler a entrada linha por linha assim:

while IFS= read -r remote; do
    ssh -n "$remote" 'rm -f /tmp/log52.log'
done <list

Estou usando ssh -naqui para parar sshde ler seu fluxo de entrada padrão (que estaria conectado ao listarquivo). Sem -n, sshleria o conteúdo restante liste seu loop executaria apenas uma única iteração.

Alternativamente, se você realmente deseja ler os comandos de um documento aqui:

while IFS= read -r remote; do
    ssh -T "$remote" <<'END'
rm -f /tmp/log52.log
END
done <list

Aqui, estou usando ssh -Tpara desabilitar explicitamente a alocação de pseudoterminais, o que não é necessário, pois não estamos fazendo nada que exija interação do usuário. Estou fazendo isso porque sshperceberei que seu fluxo de entrada padrão contém dados, então nos avisará sobre não ter um terminal funcionando no sistema remoto para fazer coisas interativas. Não precisamos -nde with sshaqui, pois estamos reatribuindo o fluxo de entrada padrão sshdo documento aqui.

Mas o loop poderia ser substituído pelo único comando

xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list

... onde o xargsutilitário irá lerlinhasdo arquivo list, substitua {}no sshcomando por uma linha lida do arquivo e execute a ação de acessar os sistemas remotos para excluir o arquivo específico. Estou usando rm -fpara não causar erro se não houver nenhum arquivo para excluir.

Algumas implementações xargspermitem a execução paralela do utilitário, por exemplo -P 4(manteria no máximo quatro sshcomandos simultâneos ao mesmo tempo).

Responder2

#! /bin/bash
for i in `cat list`
do
    echo $i
    echo "-------------------------"
    ssh $i "rm /tmp/log52.log"
done

Se você precisar remover apenas um único arquivo, basta especificá-lo em uma linha. Além disso, você pode achar útil adicionar -fao arquivo rm.

Responder3

Você não pode simplesmente redirecionar o stdin de uma sessão ssh como essa. Você deverá ver uma mensagem de erro semelhante a:

O pseudoterminal não será alocado porque stdin não é um terminal

Você precisa usar a opção -tt para ssh para forçar a alocação de um pseudotty. Experimente isto:

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS

informação relacionada