execute qm monitor commands in shell script

shrikant2002

Member
Dec 13, 2020
1
0
6
32
If I execute this below lines on proxmox shell to wakeup my mac os it works flawlessly but in shell script (.sh) it doesn't work
qm monitor 503
system_wakeup
quit


I tried this code which is posted as solution in another question but it throws an error "2022/02/19 12:02:58 socat[6449] E connect(5, AF=1 "/var/run/qemu-server/503.mon", 30): No such file or directory"

#!/bin/bash

QEMU_MONITOR_SOCKET_PATH=/var/run/qemu-server
QEMU_MONITOR_SOCKET_EXT=mon
SOCAT=$(which socat) || { echo "socat cmd not found => exit"; exit 1; }
VMID=503
command="command you want to run in qemu monitor"

echo "${command}" | ${SOCAT} unix-connect:${QEMU_MONITOR_SOCKET_PATH}/${VMID}.${QEMU_MONITOR_SOCKET_EXT} stdio

exit 0
 
the extension should be 'qmp' not 'mon'
 
Hello i am interested in this subject too,

I try this code :
Code:
plRunQmCommand() {
    qmsp=/var/run/qemu-server
    qmse=qmp
    soc=$(which socat) || { echo "socat cmd not found => exit"; exit 1; }
    vmid=$1
    command=$2 # "info usb"
    echo "${command}" | ${soc} unix-connect:${qmsp}/${vmid}.${qmse} stdio
    exit 0
}

plRunQmCommand 100 "info usb"

and i get this result :
Code:
{"QMP": {"version": {"qemu": {"micro": 1, "minor": 1, "major": 6}, "package": "pve-qemu-kvm_6.1.1"}, "capabilities": []}}
{"error": {"class": "GenericError", "desc": "JSON parse error, invalid keyword 'info'"}}
{"error": {"class": "GenericError", "desc": "JSON parse error, invalid keyword 'usb'"}}

instead of this :
Code:
qm> info usb
  Device 0.1, Port 1, Speed 480 Mb/s, Product QEMU USB Tablet, ID: tablet
  Device 1.0, Port 1, Speed 1.5 Mb/s, Product USB Host Device, ID: usb0
  Device 1.1, Port 2, Speed 12 Mb/s, Product CORSAIR K57 RGB Wireless Gaming, ID: usb1
  Device 1.3, Port 3, Speed 12 Mb/s, Product CORSAIR DARK CORE RGB SE Gaming, ID: usb2
  Device 1.2, Port 4, Speed 12 Mb/s, Product SB X-Fi Surround 5.1 Pro, ID: usb3
qm>

Where is my mistake please ?

I want to automate mounting all my usb devices :
Code:
# cd /etc/pve/qemu-server
# cp 110.conf 110.conf.bak
# qm set 110 -args "\
-device qemu-xhci,id=xhci1 \
-device usb-host,bus=xhci1.0,hostbus=3,hostport=1.1,id=Device_1 \
-device usb-host,bus=xhci1.0,hostbus=3,hostport=1.2,id=Device_2 \
-device usb-host,bus=xhci1.0,hostbus=3,hostport=1.3,id=Device_3 \
-device qemu-xhci,id=xhci2 \
-device usb-host,bus=xhci2.0,hostbus=7,hostport=1,id=Device_14 \
-device usb-host,bus=xhci2.0,hostbus=7,hostport=3,id=Device_5 \
-device usb-host,bus=xhci2.0,hostbus=7,hostport=4.3.1,id=Device_6 \
"
# qm start 110

Code:
# qm monitor 110
qm> info usb
  Device 0.1, Port 1, Speed 480 Mb/s, Product QEMU USB Tablet, ID: tablet
  Device 2.1, Port 1, Speed 480 Mb/s, Product Device_1, ID: Device_1
  Device 2.2, Port 2, Speed 480 Mb/s, Product Device_2, ID: Device_2
  Device 2.3, Port 3, Speed 12 Mb/s, Product Device_3, ID: Device_3
  Device 3.1, Port 1, Speed 12 Mb/s, Product Device_4, ID: Device_4
  Device 3.2, Port 2, Speed 1.5 Mb/s, Product USB Keyboard, ID: Device_5
  Device 3.3, Port 3, Speed 12 Mb/s, Product Apple Keyboard, ID: Device_6
qm> quit

Help please :)

Best regards
 
Last edited:
I also did not succeed with qmp, it seems, that it just does not have "info" command.
But you could use expect utility to interact with qm monitor shell.

Bash:
#!/bin/sh

run_command()
{
    vmid=$1
    cmd=$2

    # We are using expect to run command and fetch it's output.
    output=`expect <<EOD
log_user 0
spawn qm monitor $vmid
expect "qm> "
send "$cmd\n"
expect -re "(.*)qm> "
puts \\$expect_out(1,string)
send "quit\n"
EOD
`

    # Remove CR character, remove first line (it is the command itself).
    echo -n "$output" \
        | tr -d '\r' \
        | sed '1d'
}

run_command 100 "info usb"

You could also check this script, which I use to quickly attach usb devices to running VMs.
 
'qm monitor' uses HMP (the Human Monitor Protocol), whereas QMP uses the regular Qemu Monitor Protocol. see 'man qemu-qmp-ref' for what the latter offers as commands/parameters.
 
you could use human-monitor-command with qmp

Bash:
#!/bin/bash
QEMU_MONITOR_SOCKET_PATH=/var/run/qemu-server
QEMU_MONITOR_SOCKET_EXT=qmp
SOCAT=$(which socat) || { echo "socat cmd not found => exit"; exit 1; }
VMID=503
command="{ 'execute': 'qmp_capabilities' }
{ 'execute': 'human-monitor-command',
     'arguments': { 'command-line': '$@' } }
"

echo "${command}" | ${SOCAT} unix-connect:${QEMU_MONITOR_SOCKET_PATH}/${VMID}.${QEMU_MONITOR_SOCKET_EXT} stdio \
| tail -n -1|jq .[] |xargs echo -e #prettify output
exit 0

Bash:
root> VMID=100 ./script.sh info usbhost
  Bus 1, Addr 5, Port 8, Speed 12 Mb/s
    Class e0: USB device 8087:0029
  ......
 
Last edited:

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!