
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 do
and done
, o que causaria erros de sintaxe, e que você está usando i
como variável de loop, mas tente conectar-se a alguma server
variável que pode não estar definida.
Além disso, você está usando cat
uma 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 -n
aqui para parar ssh
de ler seu fluxo de entrada padrão (que estaria conectado ao list
arquivo). Sem -n
, ssh
leria o conteúdo restante list
e 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 -T
para 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 ssh
perceberei 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 -n
de with ssh
aqui, pois estamos reatribuindo o fluxo de entrada padrão ssh
do documento aqui.
Mas o loop poderia ser substituído pelo único comando
xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list
... onde o xargs
utilitário irá lerlinhasdo arquivo list
, substitua {}
no ssh
comando 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 -f
para não causar erro se não houver nenhum arquivo para excluir.
Algumas implementações xargs
permitem a execução paralela do utilitário, por exemplo -P 4
(manteria no máximo quatro ssh
comandos 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 -f
ao 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