在遠端機器上執行 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"

相關內容