Executar se a instrução na máquina remota

3

Estou tentando executar um conjunto de comandos em uma máquina remota, que inclui uma instrução if. Estou usando isso para encerrar uma lista de instâncias kvm. A primeira linha deve estar bem, mas poderia ser mais bonita, o resto precisa de ajuda.

ssh root@kvmsrv 'virsh shutdown $host 2> /dev/null; virsh destroy $host 2> /dev/null; sleep 2; virsh undefine $host 2> /dev/null'

# Also needs to be run on remote machine
# to disconnect iscsi
iscsiadm -m session | grep $host
if [ $? == 0 ]; then
  iscsiadm -m node -T $stserver.$host -u
fi

# then on local machine
tid='ssh root@storage1 'cat /proc/net/iet/volume' | grep $host | head -1 | awk '{print $1}' | awk -F: '{print $2}''
if [ $tid ]; then
  echo "Deleting tid:$tid from $stserver."
  ssh root@$stserver "ietadm --op delete --tid=$tid"
fi

Eu acho que eu poderia fazer o mesmo para a segunda parte, apenas separar tudo; mas se alguém for ler meu código mais tarde, eles provavelmente estarão coçando a cabeça ...

Existe uma maneira de formatar tudo isso para que seja legível e ainda faça sentido e todos os comandos remotos sejam executados corretamente?

    
por Robert 16.06.2012 / 00:23

4 respostas

4

  1. Coloque sua longa e complexa seqüência de comandos em seu próprio shell script, vamos chamá-lo virsh-shutdown-remote.sh

  2. Execute ssh e use o redirecionamento de entrada para executar o script:

    ssh root@kvmsrv < virsh-shutdown-remote.sh
    

Colocar os comandos em um script é uma boa ideia em qualquer caso.

Como uma dica extra, em vez disso:

iscsiadm -m session | grep $host
if [ $? == 0 ]; then
  iscsiadm -m node -T $stserver.$host -u
fi

Você pode escrever a mesma coisa mais simples e mais curta em uma única linha:

iscsiadm -m session | grep $host && iscsiadm -m node -T $stserver.$host -u
    
por 17.06.2012 / 10:10
2

Você pode usar HEREDOCS , por exemplo:

ssh root@kvmsrv <<EOF
  virsh shutdown $host 2> /dev/null
  virsh destroy $host 2> /dev/null
  sleep 2
  virsh undefine $host 2> /dev/null

  # to disconnect iscsi
  iscsiadm -m session | grep $host
  if [ \$? == 0 ] ; then
    iscsiadm -m node -T $stserver.$host -u
  fi
EOF

Por favor, esteja ciente de que escapei de $? , caso contrário, seria avaliado pelo seu shell local e não pelo seu shell remoto. Como $host parece estar definido localmente, você não terá que escapar dela.

Apenas um pequeno comentário, embora você não tenha pedido. Você pode executar remotamente comandos virsh, sem a necessidade de explicitamente ssh no host, por exemplo:

virsh -c qemu+ssh://root@kvmsrv/system destroy host

funcionará. Você também não precisa do ssh, pois o libvirt permite que você autentique com certificados de certificados SSL.

    
por 16.06.2012 / 03:51
0

Talvez apenas adicione comentários para explicar coisas que (deveriam) ser óbvias? Eu faço isso regularmente em roteiros para lembrar a minha própria bunda ignorante o que eu estava fazendo quando escrevi a coisa [censurada] em primeiro lugar.

    
por 16.06.2012 / 00:31
0

Bem, a resposta simples é que é possível reescrever ssh root@kvmsrv 'cmd1; cmd2; cmd3' como:

ssh root@kvmsrv '
cmd1
cmd2
cmd3
'

A única coisa a lembrar é que as aspas simples "dentro" de aspas simples devem ser expressas como: '\'' . Exemplos:

ssh localhost '
echo hi
whoami
ls -ld /
var="'\''"
echo "$var"
if [ $? == 0 ]; then
   echo "escaping single quote worked"
fi
'

# get single quote from file and print it
echo "'" > sqfile
ssh localhost '
#set -xv
echo hi
cat sqfile
var="$(cat sqfile)"
echo "$var"
'

# pass a single quote to the remote host and print it
# while keeping the outer single quotes for the ssh command
escsquote="'\''"
squote="'"
squote="'${squote//\'/${escsquote}}'" # bash

ssh localhost 'sh -c '\''
#set -xv
echo hi
echo "$1"
'\''' _ "$squote"
    
por 13.02.2014 / 10:39