我正在嘗試在遠端電腦上執行一組命令,其中包括 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
將你的長而複雜的命令序列放在它自己的 shell 腳本中,我們稱之為
virsh-shutdown-remote.sh
運行
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"