web-dev-qa-db-ja.com

リモートマシンで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

2番目の部分でも同じことができると思いますが、すべてを;で区切ってください。しかし、誰かが後で私のコードを読みに行くとしたら、おそらく頭を悩ませているでしょう...

これらすべてをフォーマットして、読みやすく、それでも意味があり、すべてのリモートコマンドを正しく実行する方法はありますか?

4
Robert
  1. 長くて複雑な一連のコマンドを独自のシェルスクリプトに入れて、それを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

同じことを1行でもっと簡単に短く書くことができます。

iscsiadm -m session | grep $Host && iscsiadm -m node -T $stserver.$Host -u
4
janos

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

私が逃げたことに注意してください$?そうでない場合は、リモートシェルからではなく、ローカルシェルによって評価されます。なので $Hostローカルで定義されているようです。エスケープする必要はありません。

あなたはそれを求めなかったけれども、ほんの少しのコメント。ホストに明示的にsshする必要なしに、virshコマンドをリモートで実行できます。例:

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

働くでしょう。 libvirtでは代わりにsslcertsで認証できるため、sshも必要ありません。

3
Ulrich Dangel

簡単な答えは、実際には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"
0
marc

たぶん、明白なことを説明するためにコメントを追加するだけですか?私はこれをスクリプトで定期的に行って、最初に[検閲済み]のものを書いたときに何をしていたかを自分の無知な尻に思い出させます。

0
killermist