Skip to content

Instantly share code, notes, and snippets.

@zambonin
Last active April 12, 2024 09:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zambonin/fb195abe7ef2e7530819b9baea9bb99b to your computer and use it in GitHub Desktop.
Save zambonin/fb195abe7ef2e7530819b9baea9bb99b to your computer and use it in GitHub Desktop.
AWK script to send multiple `sendkey` commands to a QEMU virtual machine.
#!/usr/bin/env awk -f
#
# AWK script to send multiple `sendkey` commands to a QEMU virtual machine.
# It writes at a rate of roughly 40 keys per second, due to lower delays
# resulting in garbage output.
#
# It makes use of a TCP client created by an external utility, such as OpenBSD
# Netcat, to interact with QEMU's monitor and send a stream of `sendkey`
# commands. This is a practical way to transfer a small file or to script
# interactions with a terminal user interface.
#
# While running a QEMU virtual machine with the option
#
# -monitor tcp:localhost:$PORT,server,nowait
#
# where $PORT is a non-privileged (>1024) port of choice, one can use
#
# $ echo "foobar" | awk -f sendkeys.awk | nc localhost $PORT -q1
# $ awk -f sendkeys.awk /path/to/file | nc localhost $PORT -q1
#
# to send multiple keys to the virtual machine. The variable `delay` is a wait
# period in seconds that is inserted between each `sendkey` command. It has
# a default value of 0.025 and can be customized through the command line, such
# as in the example below.
#
# $ echo "deadbeef" | awk -v delay=1 -f sendkeys.awk | nc localhost $PORT -q1
BEGIN {
key["#"] = "backspace"
key[" "] = "tab"
key[" "] = "spc"
key["!"] = "shift-1"
key["\""] = "shift-apostrophe"
key["#"] = "shift-3"
key["$"] = "shift-4"
key["%"] = "shift-5"
key["&"] = "shift-7"
key["'"] = "apostrophe"
key["("] = "shift-9"
key[")"] = "shift-0"
key["*"] = "shift-8"
key["+"] = "shift-equal"
key[","] = "comma"
key["-"] = "minus"
key["."] = "dot"
key["/"] = "slash"
for (i = 48; i < 48 + 10; ++i) {
number = sprintf("%c", i)
key[number] = number
}
key[":"] = "shift-semicolon"
key[";"] = "semicolon"
key["<"] = "shift-comma"
key["="] = "equal"
key[">"] = "shift-dot"
key["?"] = "shift-slash"
key["@"] = "shift-2"
for (i = 65; i < 65 + 26; ++i) {
key[sprintf("%c", i)] = sprintf("shift-%c", i + 32)
}
key["["] = "bracket_left"
key["\\"] = "backslash"
key["]"] = "bracket_right"
key["^"] = "shift-6"
key["_"] = "shift-minus"
key["`"] = "grave_accent"
for (i = 97; i < 97 + 26; ++i) {
lower = sprintf("%c", i)
key[lower] = lower
}
key["{"] = "shift-bracket_left"
key["|"] = "shift-backslash"
key["}"] = "shift-bracket_right"
key["~"] = "shift-grave_accent"
key[""] = "delete"
if (!delay) {
delay = 0.025
}
}
{
split($0, chars, "")
for (i = 1; i <= length($0); i++) {
printf("sendkey %s\n", key[chars[i]])
system("sleep " delay)
}
printf "sendkey ret\n"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment