execute qm monitor commands in shell script

shrikant2002

Member
Dec 13, 2020
1
0
6
33
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: