Embedding other scripting languages in Bash

Graphical User Interfaces

You can use command-line tools like Zenity and YAD to create graphical dialogs. If you're interested in creating custom dialogs, all the major scripting languages have options that can be used.

In the earlier Python example, Bash variables were passed into the embedded Python code with the $((bash_variable)) syntax. Unfortunately, this approach may not work with all scripting languages, so an alternative method is to pass data back and forth with environment variables.

For this example, I'll be using an old-school GUI scripting language called wish, and hardware information will be passed into wish with environmental variables. To install wish on Debian, Ubuntu, or Raspberry Pi systems use

# To install tcl/wish,
# a GUI scripting language
sudo apt install tcl wish

In Listing 6, notebook.sh creates two environmental variables, VAR1 and VAR2 (lines 5 and 6). VAR1 is the output from df, the command-line reporting tool for disk file usage, and VAR2 contains the result from lsusb, a utility for listing USB devices. A window with the notebook object and two frames is created in lines 10 through 16. Within the tab frames, two labels are used to show the Bash environment variables (lines 20-21). Figure 3 shows the df disk file information along with the notebook.sh script results in a wish tabbed dialog.

Listing 6

Bash Using a Wish Tabbed Dialog

01 # notebook.sh - show hardware details in a tabbed dialog -
02 #!\bin\bash
03
04 # Create some environment variables with hardware info
05 export VAR1=$(df -P) ; # disk info
06 export VAR2=$(lsusb) ; # list USB devices
07
08 wish << END
09
10 # Create a two tab notebook in Wish
11 wm title . "Hardware Info"
12 ttk::notebook .n  -width 1000 -height 400
13 ttk::frame .n.f1;
14 ttk::frame .n.f2;
15 .n add .n.f1 -text "Disk Usage"
16 .n add .n.f2 -text "USB Devices"
17
18 # read the environment variables and put the text a tab's label
19 font create myFont -family Terminal -size 12
20 pack [label .n.f1.f1 -justify left -font myFont -text $::env(VAR1) ]
21 pack [label .n.f2.f2 -justify left -font myFont -text $::env(VAR2) ]
22 pack .n
23
24 END
Figure 3: Using a Bash script to pass hardware information into an embedded wish dialog script.

Raspberry Pi Hardware Interface

A rich set of tools exists for Bash scripts to analyze and monitor laptop and server hardware. Unfortunately, Bash support is weak for Raspberry Pi peripherals such as sensors and display devices.

To address this weak support, I will use Bash to find the current usage on all the Raspberry Pi USB ports and compare it to the maximum allowable current. This is a task that is well-suited for a Bash script, but it might be a little challenging to do in Python. I want to display the current usage results on both the terminal and a 2x16 I2C LCD screen. Because the LCD screen hardware doesn't have a Bash interface, I again will use some embedded Python statements.

Figure 4 shows my setup. The I2C LCD screen is connected with the SDA (Serial Data) wired to physical pin 3 (GPIO2) and the SCL (Serial Clock) wired to physical pin 5 (GPIO3). To simulate a USB current load, I use a Lexar JumpDrive and a TEMPer temperature sensor.

Figure 4: The I2C LED screen connected to a Rasp Pi shows the current usage on the Rasp Pi.

The lsusb command-line tool can present a detailed list of the currently connected USB devices. Figure 5 shows the steps for identifying each USB device and then the statement needed to calculate the total used current. For my setup, a TEMPer sensor (ID 413d:2107) creates a 100mA load, and a Lexar JumpDrive adds another 200mA.

Figure 5: Using lsusb to calculate the total current used on a Rasp Pi.

The script current2lcd.sh (Listing 7) outputs to the terminal the current usage for each USB device and the total used current (Figure 6). Embedded Python is used to define the 2x16 LCD screen and show the USB current total along with the Rasp Pi maximum allowable mA value (lines 17-25).

Listing 7

Current Usage Output on Rasp Pi

01 # current2lcd - get USB current used, show results on 2x16 LCD
02 #           - use embedded Python so Bash can access LCD
03 #!\bin\bash
04
05 # Get the max used current from lsusb utility
06 # show results at terminal
07 echo -e "USB Current Used\n"
08 sudo lsusb -v  2>&- | grep -E  'Bus 00|MaxPower'
09
10 # calculate max Amps and put into variable
11 maxA=$(sudo lsusb -v 2>&- | grep MaxPower | \
12        grep -o -E '[0-9]+' | awk '{ sum += $1} END {print sum }')
13
14 echo -e "\nMax used current: $maxA mA"
15 echo -e "Pi 3/4 max allowable: 1200mA\n"
16
17 python3 << END
18
19 # Python code to send current info to 2x16 LCD
20 import rpi_lcd
21 lcd = rpi_lcd.LCD();
22 lcd.text("USB used: $((maxA)) mA", 1)
23 lcd.text("Pi max:  1200 mA", 2)
24
25 END
Figure 6: The Rasp Pi USB current usage is displayed on the terminal.

For charting, I've looked at integrating Python so far, but these examples could also be done in Julia or R.

Summary

Embedding another scripting language into your Bash script will remove the need for creating extra standalone programs, and it allows you to put all your code in one place.

One question that is often asked is: "When should I be using Python within Bash versus Bash within Python?" It's nice to know that you have both options, but I think the answer depends on where most of the work is being done.

If you find that you're doing a lot of both Python and Bash work, you might want to consider looking at Xonsh [5], a Python-powered shell.

The Author

You can investigate more neat projects by Pete Metcalfe and his daughters at https://funprojects.blog.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Tutorial – Shell Scripting

    You do not need to learn low-level programming languages to become a real Linux power user. Shell scripting is all you need.

  • Bash 5.0

    It's a coincidence that the Linux kernel and Bash jumped to version 5.0 at about the same time. While Linus assigns the numbers as he sees fit, Bash changes its version when major adjustments are made. Here's what users can expect in Bash 5.

  • Xonsh

    Create lightweight Raspberry Pi scripts with Xonsh, a Python shell that lets you write scripts in Python with Bash commands mixed in.

  • Ren'Py

    Ren'Py helps you create Android, Linux, macOS, Windows, and HTML5 games and apps.

  • How Does ls Work?

    A simple Linux utility program such as ls might look simple, but many steps happen behind the scenes from the time you type "ls" to the time you see the directory listing. In this article, we look at these behind-the-scene details.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News