Linux Format

Interactiv­e scripting with Whiptail

Spruce up those interactiv­e shell scripts! Create a text-based wizard using a clever little tool called Whiptail and a little shell scripting.

-

In the command-line world, programs usually run noninterac­tively: you supply all the needed file names, options and whatnot on the command line, hit Enter, and let it get on with it. But some users prefer to be prompted for needed informatio­n a piece at a time. That’s why wizards were born.

If you want to perform step-by-step informatio­n gathering inside a shell script, the traditiona­l prompt-then-read approach might look like this: echo -n "Enter file name to process: "read FILENAME ... and so on. But this approach is visually dull, and it’s not easy to do things like menu choices or checkbox selections. An alternativ­e is a tool called Whiptail that lets you present various informatio­n-gathering dialogs from within a script.

Whiptail offers several different dialogs, listed in the table. Most provide for some sort of user input, from simple yes/no decisions to free-format text input. Some are just for output. To show off a few of these I wrote a simple script that walks the user through the process of changing permission­s on a file or folder and ends up building a chmod command. It’s not intended to be real-worldly, just a proof of concept. Here’s the script. The line numbers are for reference, not part of the file. 1 #!/bin/bash 2 3 FILENAME=$(whiptail --inputbox \ 4 "Enter file or folder name:" \ 5 8 78 --title "File selection" 3>&1 1>&2 2>&3) 6 7 exitstatus=$? 8 if [ $exitstatus != 0 ] 9 then 10 exit 1 # User cancelled 11 fi 12 13 RECURSIVE="" 14 if [ -d $FILENAME ] # User chose a directory 15 then 16 if (whiptail --title "Apply to folder?" --yesno \ 17 " You entered the name of a folder. Do you want 18 to apply the change to all files in the folder?" \ 19 8 78) 20 then 21 echo recursive option selected 22 RECURSIVE="-R" 23 fi 24 fi 25 26 MODES=$(whiptail --title "Select permission­s" \ 27 --checklist \ 28 "choose permission­s" 10 78 4 \ 29 r Read ON \ 30 w Write OFF \ 31 x Execute OFF 3>&1 1>&2 2>&3 | tr -d -c rwx ) 32 exitstatus=$? 33 if [ $exitstatus != 0 ] 34 then 35 exit 1 # User cancelled 36 fi 37 38 whiptail --title "Confirmati­on" --msgbox \ 39 "chmod $RECURSIVE u=$MODES $FILENAME" 8 78

Before working through the script, let me explain how Whiptail interacts with the outside world. First, text input gathered from the user, for example using an inputbox, is written to the standard error stream. This makes life a little awkward because you can’t easily capture it into a variable (using command substituti­on) or pipe it somewhere. I’ll show you a trick to deal with this in a minute. Second, yes/no and OK/cancel decisions made by the user are communicat­ed back through the program’s exit status: ‘yes’ or ‘ok’ selections return zero, ‘no’ or ‘cancel’ selections return non-zero.

So, let’s dissect the script. Lines 3-5 present an input box to get the filename from the user. The title text ‘File Selection’ appears at the top of the box and the text ‘Enter file or folder name’ appears as a prompt within the box. The numbers (8 and 78) set the width and height. Whatever the user enters is written to standard error. However, the strange three-step dance 3>&1 1>&2 2>&3 at the end of the command swaps standard error with standard output, so that we can capture the output of the command into the variable FILENAME using command substituti­on. Cunning, but messy!

We also test the exit status (lines 7-11). If the user selects ‘Cancel’ to dismiss the dialog, Whiptail returns a non-zero exit status and we simply abandon the task, exiting our script.

Next (line 14) we test whether the name the user enters is a directory. If so, we present a yes/no dialog (lines 16-23) to ask if the user wants to change the permission­s just on the folder or on all the files inside it. Here we test the exit status directly, setting the RECURSIVE variable if the answer is ‘yes’. Next, lines 26-31 present a list of checkboxes, so the user can select any combinatio­n of read, write and execute permission. Whiptail’s output from this will be a string, something like "r" "w" So we strip off the extraneous quotes and spaces by piping into tr (line 31) and capture the result in MODES. Finally (lines 38-39) we display the chmod command we’ve built in a message box.

Newspapers in English

Newspapers from Australia