Showing GUIs from Shell Scripts
source link: https://sixtyfps.io/blog/showing-guis-from-shell-scripts.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Showing GUIs from Shell Scripts
Posted on October 12, 2021 by Olivier Goffart and Simon Hausmann
Ever written a quick (shell) script to automate a small task at some point? Then that script grew over the years and perhaps ended up in the hands of way more users than you originally anticipated?
If you were lucky enough to experience this, maybe you wondered: Wouldn't it be nice to have a GUI for that script?
Now, you probably don't want to rewrite this script in another language to get access to powerful GUI libraries. But you still want to use a proper GUI library. And you also want something that accepts and returns complex, structured data. Finally, this GUI should run eveywhere that script runs.
Teaser
If you have rust/cargo installed, copy this code snippet and paste it into your shell on Linux or macOS.
#!/bin/bash
# install sixtyfps-viewer (do nothing if it is already installed)
cargo install sixtyfps-viewer
output=$(sixtyfps-viewer - --save-data - << EOF
import { StandardButton, LineEdit, GridBox } from "sixtyfps_widgets.60";
_ := Dialog {
StandardButton { kind: ok; }
StandardButton { kind: cancel; }
property name <=> name-le.text;
property address <=> address-le.text;
GridBox {
Row {
Text { text: "Enter your name:"; }
name-le := LineEdit { }
}
Row {
Text { text: "Address:"; }
address-le := LineEdit { }
}
}
}
EOF
)
if [ $? -eq 0 ]; then
name=`echo $output | grep -o '"name": *"[^"]*"' | grep -o '"[^"]*"$'`
address=`echo $output | grep -o '"address": *"[^"]*"' | grep -o '"[^"]*"$'`
echo "Your name is $name and you live in $address"
fi
cargo install sixtyfps-viewer
out=$(sixtyfps-viewer - --save-data - \
<<
)
[ $? -eq 0 ];
name=` \
| grep -o \
| grep -o `
address=` \
| grep -o \
| grep -o `
You should see the following dialog. When you click OK, it prints
Your name is "Olivier" and you live in "Berlin"
.
Using SixtyFPS from Shell Scripts
SixtyFPS is a new GUI framework for desktop and embedded applications. It is written in Rust but can be used from other programming languages.
The sixtyfps-viewer
utility is a tool that we introduced to preview .60
design markup files.
Since it is written in Rust, you can install it by running cargo install sixtyfps-viewer
. Besides the preview functionality, we have added
features that help you show GUIs from shell scripts.
The .60
design markup language describes your UI in a declarative way
with a familiar syntax. Check out our language
reference for details.
With sixtyfps-viewer
, you can either load a .60 file, or pass a "-
" to load from stdin.
The design is then shown on the screen and you can interact with it like a real application.
What's new is that any properties declared at the top-level can be loaded and saved with JSON. The
--save-data -
option causes the the viewer to write the properties as key-value pairs
to stdout when quitting, or you could also write it into a temporary file. The --load-data
option reads a JSON object and populates the key-value pairs to the properties declared at the top-level.
To persist the value of widgets like LineEdit
, declare aliases, similar to the teaser
example: property name <=> name-le.text;
This re-exports the name-le
's text property as
"name".
SysInfo Example
You can find a more advanced example in our Git repository:
This
sysinfo_linux.sh
script collects information about your system, formats it to JSON, feeds it into sixtyfps-viewer
and presents a system
information dialog. Next to it is sysinfo_mac.sh
script that does the same for macOS, and they both use the same user interface file
.
On Linux it looks like this:
Conclusion
These examples demonstrate a simple way of separating a dialog user interface from input and output data. There are many ways how this could be extended, for example by feeding dynamically data updates via another file descriptor on the side, or by specifying custom callbacks.
What kind of features would you be interested in using to enhance your shell scripts with a UI? Let us know in the comments.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK