我正在尝试重新启动、启动、关闭特定虚拟机。 在这里,首先我想在运行脚本之前检查虚拟机是否已处于所需状态。
这些是虚拟机列表。
[root@demohost05 ~]# virsh list --all
Id Name State
----------------------------------------------------
5 OwnCloud01 running
6 OwnCloud02 running
7 SiteMon running
- vmtest shut off
我想在实施之前检查 vmtest 是否正在运行
virsh start vmtest
如何在 shell 脚本中使用 if 条件检查状态?
当我必须使用 sudo 命令时,如何避免输入密码。
sudo virsh start vmtest
我还尝试使用
授予 root 权限sudo -i
virsh start vmtest
但是脚本结束时没有执行第二行。 如何在同一个脚本文件中使用这两个命令?
if [conditions]
then
{
}
fi
我不知道如何检查此类脚本的条件。
谢谢你。
试试这个:
tmp=$(virsh list --all | grep " vmtest " | awk '{ print $3}')
if ([ "x$tmp" == "x" ] || [ "x$tmp" != "xrunning" ])
then
echo "VM does not exist or is shut down!"
# Try additional commands here...
else
echo "VM is running!"
fi
# For passwordless sudo:
sudo cat /etc/sudoers
# You'll see this:
# User privilege specification
root ALL=(ALL:ALL) ALL
# To add user sharad as a sudo user:
# User privilege specification
root ALL=(ALL:ALL) ALL
sharad ALL=(ALL:ALL) ALL
# To add user sharad as a sudo user such that it doesn't ask for password (note the NOPASSWD):
# User privilege specification
root ALL=(ALL:ALL) ALL
sharad ALL=(ALL:ALL) NOPASSWD: ALL
# Read this for reference: http://www.ducea.com/2006/06/18/linux-tips-password-usage-in-sudo-passwd-nopasswd/
我喜欢 Sharad 的回答,但我在等待虚拟机关闭时将其反转为繁忙循环
virsh shutdown $VM
state=$(virsh list --all | grep " $VM " | awk '{ print $3}')
while ([ "$state" != "" ] && [ "$state" == "running" ]); do
sleep 10
state=$(virsh list --all | grep " $VM " | awk '{ print $3}')
done;
# now do something else to the shutdown VM and finally restart it
virsh start $VM
就我而言,我在虚拟机关闭时创建快照,然后重新启动它。我将 10 秒的睡眠硬编码到循环中,因为这似乎是一个合理的重试周期,因为 Windows 虚拟机在安装更新时可能需要很长时间 - 可能是几分钟甚至更长。
基于 Sharad 和 Gary 的答案,但仅查询相关虚拟机的状态。
virsh shutdown $VM
state=$(virsh dominfo $VM | grep -w "State:" | awk '{ print $2}')
while ([ "$state" != "" ] && [ "$state" == "running" ]); do
sleep 10
state=$(virsh dominfo $VM | grep -w "State:" | awk '{ print $2}')
done;
# now do something else to the shutdown VM and finally restart it
virsh start $VM
我的场景有点不同,所以我得到了稍微不同的解决方案。
我想启动一台虚拟机 (Windows) 并通过
xfreerdp
全部在一个脚本中连接到它。为此,端口 3389 必须在 VM 内打开,启动 VM 后情况并非如此,尽管 virsh list --all
返回“正在运行”。所以这是我的小脚本,使用 nc
(又名 netcat
)来检查端口:
# "windows_vm" is the VM-name, while "windows_guest" is the VM's hostname
virsh dominfo windows_vm | grep 'State: *shut off'
if [ $? -eq 0 ]; then
echo "Start windows_vm..."
virsh start windows_vm
while true; do
echo "Waiting for start..."
# nc-parameters:
# -w1: wait 1s
# -z: ony scan the port without sending data
nc -w1 -z windows_guest 3389
if [ $? -eq 0 ]; then
break
fi
sleep 1
done
fi
xfreerdp /v:windows_guest ...some-more-parameters...
如果 Windows 中未启用远程桌面功能,您可能可以检查其他端口。
如果来宾是 Linux-VM,端口 22 总是值得一试。
我刚刚在看这个。有一个内置命令,而不是通过管道连接到
grep
和 awk
。我不知道第一次问这个问题时是否是这种情况,但对于其他可能遇到此问题的人来说:
virsh domstate <vm name>
确保使用的名称引号中包含空格。 此外,仅当名称中不含空格时,接受的答案才有效。如果确实有空格,则需要调整
awk
命令。
如果您不需要使用
virsh
命令,在 Ubuntu 上,运行域名有一个 PID 文件和运行 XML 配置文件,位于 "/var/run/libvirt/qemu/${DomainName}.{pid,xml}"
。
我编写了一个脚本,在文件存在的情况下启动域。这样我就不必切换域自动启动选项。
================================================================================
2022/01/15 16:18:42: Okay to start.
2022/01/15 16:18:42: 'ParrotKde' appears to be running already. PID = 24470.
2022/01/15 16:18:45: 'UbuntuServer20' has been started. PID = 25209.
================================================================================
2022/01/15 16:20:45: '/scripts/startvms' doesn't exist. Aborting.
当我必须使用 sudo 命令时,如何避免输入密码。
确保您的用户是“libvirt”组的成员。
sudo usermod -G libvirt <username>
您需要注销并重新登录才能生效。
请注意,在基于 RHEL 的系统上,您可能还需要确保设置了以下环境变量:
LIBVIRT_DEFAULT_URI=qemu:///system
然后尝试:
$ virsh domstate vmtest
running
不幸的是,上面的内容并没有为您提供一个很好的简单退出代码来在 bash 中进行测试,因此您可以尝试以下操作(针对未运行的机器显示的输出):
$ virsh domstate vmtest | grep running
$ echo $?
1
Bash 脚本如下所示:
#!/bin/bash
virsh domstate vmtest | grep running
if [ $? -ne 0 ] ; then
echo Starting VM vmtest
virsh start vmtest
fi