在远程机器上运行 if 语句

在远程机器上运行 if 语句

我正在尝试在远程计算机上运行一组命令,其中包括 if 语句。我用它来关闭 kvm 实例列表。第一行应该没问题,但还可以更漂亮,休息需要一些帮助。

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

我想我可以对第二部分做同样的事情,只需用 ; 将其全部分开即可。但如果有人稍后去阅读我的代码,他们可能会摸不着头脑......

有没有一种方法可以格式化所有这些内容,使其可读且仍然有意义,并使所有远程命令都能正确执行?

答案1

  1. 将你的又长又复杂的命令序列放在它自己的 shell 脚本中,我们称之为virsh-shutdown-remote.sh

  2. 运行ssh并使用输入重定向来运行脚本:

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

无论如何,将命令放入脚本中都是一个好主意。

作为额外的提示,而不是这个:

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

您可以在一行上更简单、更短地编写相同的内容:

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

答案2

您可以使用HEREDOCS,例如:

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

请注意,我转义了$?,否则它将由您的本地 shell 进行评估,而不是从远程 shell 进行评估。正如$host本地定义的那样,您不必逃避它。

尽管您没有要求,但只是一个小评论。您可以远程运行 virsh 命令,无需显式 ssh 到主机,例如:

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

将工作。您也不需要 ssh,因为 libvirt 允许您使用 ssl 证书进行身份验证。

答案3

也许只是添加评论来解释(应该)显而易见的事情?我经常在脚本中这样做,以提醒我自己无知的屁股,当我首先写[审查]的东西时我在做什么。

答案4

嗯,简单的答案是实际上可以重写ssh root@kvmsrv 'cmd1; cmd2; cmd3'为:

ssh root@kvmsrv '
cmd1
cmd2
cmd3
'

唯一要记住的是单引号“里面”的单引号应该表示为:'\''。例子:

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"

相关内容