Execute a instrução if na máquina remota

Execute a instrução if na máquina remota

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 do KVM. A primeira linha deve ficar boa, 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

Acho que poderia fazer o mesmo com a segunda parte, apenas separar tudo com ; mas se alguém ler meu código mais tarde, provavelmente estará coçando a cabeça ...

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

Responder1

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

  2. Execute sshe 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 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 de forma mais simples e curta em uma única linha:

iscsiadm -m session | grep $host && iscsiadm -m node -T $stserver.$host -u

Responder2

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

Esteja ciente de que eu escapei, $?caso contrário, seria avaliado pelo seu shell local e não pelo seu shell remoto. Como $hostparece estar definido localmente, você não precisará escapar disso.

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

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

vai funcionar. Você também não precisa de ssh, pois o libvirt permite a autenticação com certificados SSL.

Responder3

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

Responder4

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

ssh root@kvmsrv '
cmd1
cmd2
cmd3
'

A única coisa a lembrar é que aspas simples "dentro" 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"

informação relacionada