Fun With BASH Scripts – Random Quote Generator
One of the cool features of IMAGE BBS and C-NET was displaying fun and witty sayings during the login process (On older versions of C-Net I believe this was referred to as a Fortune Cookie.
In some ways, especially if you login to a UNIX/LINUX box via a terminal, it looks just like a giant BBS. I thought it would be fun to duplicate this feature on my Linux development box. It will also give me the opportunity to introduce to you login scripts or “Profiles”, as well as basic file manipulation.
The last 2 BASH demonstrations were taken from Commodore 64 BASIC programs, and from an IMAGE BBS +. File, so let’s switch gears here, and take our source from a CNET Amiga 3.5c module that was written by Jim Selleck of Beverly James Products. This module was included on the CNET 3.05c Demo and Productions disks, and the comments state it originated with C-Net Amiga 2.0.
Before we begin I would like to throw out a quite plug for C-Net Amiga 3, and the brilliant work done by its author Ken Pletzer. C-Net Amiga 3.05c happened to be one of the most stable, customizable, and feature rich BBS software that I had a pleasure to run. This particular module was written in ARREX, which was an Amiga port of the REXX scripting language developed by IBM and included with Amiga DOS 2.0. There is a version of REXX that will run under Linux. So maybe in the future we could actually explore some native REXX scripts running under Linux itself.
Lets quickly take a look at the original source, as REXX, and it’s features under C-Net Amiga are pretty straight forward and lend itself to very easy porting into BASH.
/******************************************************/
/* Random Quotation Generator 2 for CNet AMIGA v2 */
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* By Jim Selleck © 1992 Beverly James Products */
/* */
/* Installation: */
/* */
/* Stick this Arexx program and the QUOTATIONS file */
/* in your PFILES: directory. */
/* #*/
/******************************************************/
options results
filename = “pfiles:quotations”
if ~exists(filename) then
do
transmit ” ”
transmit ” ”
transmit “The Quotations could not be found! Please inform”
transmit “the Sysop !!!”
transmit ” ”
transmit ” ”
logentry “Quote: `”||filename||”‘ not found!”
exit
end
call open quote,filename,”R”
max = readln(quote) /* Get maximum number of entries */
num = random(0,max-1,time(‘s’))
ctr = 0
if num > 0 then
do until ctr = num*5
line = readln(quote)
ctr = ctr+1
end
transmit ” ”
transmit ” ”
ctr = 0
do until ctr = 5
line = readln(quote)
if length(line) > 1 then transmit center(strip(line),76)
ctr = ctr+1
end
call close quote
exit
The lines in the /* */ are simply comments, similar to BASH pounds #
Filename = is simply setting the path to the quotations filename in this case “PFILES:quotations”
We then have the script saying, if the file does not exist ~exists, then output the text asking the user to inform the SysOp (System Operator).
‘logentry’ is a specific CNET AREXX function that will write an entry into the systems caller log.
The next line is opens the quotations file, and then reads the first line, which will specify the number of quotes, Which is 100. Then the result ‘num’ will be a random number between 1 and the number of MAXQUOTES.
The file is then read from line X for 5 more lines, and is center justified for a 79 character line. So we have a 500 line text file, each 5 lines is a record, containing the quote and the source.
Here is our simple BASH script called ‘rand_quote.sh’. The quotations file was read directly from CNET Amiga using the WinUAE emulator and saved to a capture file.
Let’s now take a look at our BASH script. I would recommend creating this in a dev folder in your home directory, once tested you can move it in to the proper folder.
You must also download the quotations file, from the following link.
https://www.catracing.org/hendrb/wp-content/uploads/2015/06/quotations.txt
1 #! /bin/bash
2
3 # BASH script to display RANDOM QUOTE and center text depending on terminal width.
4 # BASH script and quotations taken from CNET Amiga 2 AREXX PFILE
5 # AMIGA Version Copyright 1992 Jim Selleck and Beverly James Products
6 #
7 # BASH Script (C)24MAY2015 by Brent Hendricks
8 # Script and accompaning BLOG article (C) 2015 Brent Hendricks
9 # Script and quotes are public domain, the accompaning BLOG may only be used with permission
10 # Contact brent.hendricks@catracing.org if you wish to republish the article.
11 # Please visit Brent’s World @ www.catracing.org\hendrb
12
13 ## Get Terminal Width
14 TERMWIDE=”$(tput cols)”
15 ((TERMWIDE = TERMWIDE -3))
16
17 ## Set file path
18 QUOTATIONS=/home/local_hendrb01/dev/bash/randquote/quotations
19 TEMP_QUOTATION=/home/local_hendrb01/dev/bash/randquote/temp_quotation
20
21 ## Get number of quotations
22 QUOTES=”$(cat $QUOTATIONS | wc -l)”
23 ((QUOTES = QUOTES / 5))
24
25 ## Pick a record
26
27 RECORD=$(($RANDOM % $QUOTES * 5))
28
29 ## Read Quote from Quote file
30 sed -n “${RECORD},+5p” $QUOTATIONS > $TEMP_QUOTATION
31 sed -e :a -e “s/^.\{1,${TERMWIDE}\}$/ &/;ta” -e ‘s/\( *\)\1/\1/’ $TEMP_QUOTATION
32
33 ## Remove TEMP_QUOTATION scratch file
34 rm -f “${TEMP_QUOTATION}”
NOTE: Once you download the quotation file, you will need to rename it quotations, or change the quotations path to reflect the .txt extension (WordPress does not allow the uploading of files without extensions.)
We should by now know what line 1 does, and why we put it there, but as a quick reminder, Line 1 tells *NIX which interpreter to use. Just in case the user is in, or defaults to a different shell. Additionally AT&T used to default to the Bourne Shell, while BSD defaulted to the C shell.
While not needed if you never use a different shell, it is good practice, and insures compatibility.
Lines 3 – 11 are my standard comments, comments in shell scripts are preceded by #s
Lines 14 Gets the terminal width, and line 15 subtracts 3 from it. This is for the center justification routines later in the script.
Lines 18 and 19 set our file paths.
Line 18 is the path of the actual quotation file.
Line 19 is the path of the temp file created by SED
Lines 22 and 23 gets the number of quotations from the quotations file and puts them in the variable QUOTES. Note that our script is a bit different because we use the wc command to dynamically derive the number of quotes, as long as you remember that each quote uses 5 lines. This is done with the QUOTES=”$(cat $QUOTATIONS | wc -l)” command. Note the use and format here of command substitution. I am going to get nailed here by someone much smarter with BASH scripts than I am. For the wasteful use of the cat command, when technically you could have used just the wc –l and the file name. If done this way, the output was would have been ‘500 quotations’. To save time with a filtering statement, I just had the file cat’d, and piped through wc. The value is held in the variable QUOTES, then divided by 5. Since each 5 lines is a quote.
Line 27 Picks a random quote, in steps of 5. Since it would not do us much good to start reading in the middle of quote now would it?
Lines 30 and 31 are where the real magic occur, and what took me the longest to figure out. I could read various quotes all day until the sun came home, but while BASH has a command to left and right justify, it will not center justify. Again my method and someone else’s methods might vary. I could very well have loaded the quotations file in nano, or word and center justified it and re saved it. However that defeats the purpose of learning, defeats the purpose of making your quotation file dynamic, as each time you added a quote you would have to remember to justify it. It might also look funny if someone had a different sized terminal window then you did when you justified it.
Line 30 reads the 5 lines from the quotations file, and saves it in a file called temp_quotation.
Line 31 uses sed to center justify the text in the temp file and display it to the screen. The use of SED is outside the scope of this blog, and many good descriptions are available elsewhere on the net. If you are interested in the working of stream editor. I would start here. http://www.grymoire.com/Unix/Sed.html
Line 34 simply deletes the temp file, without prompting.
There you have it! A random quote generator for *NIX!
If we want this to be just like a BBS, and display it when a user logs in, we now have several choices to make.
Do we want this script to be run only when we login, or for all users?
If you want it displayed for all users, we must first move it somewhere where they have access to execute it. For this demonstration let’s move it to the /opt volume.
We can use the mv (MOVE) command.
sudo mv ./randqutoe /opt
I have to use sudo here, because root is the owner of the opt directory, and I do not have my local username added to the root group.
Once it is moved, I can verify the entire contests of the randquote directory were copied.
If I cd to /opt/randquote, I should have two files.
-rw-rw-r--. 1 local_hendrb01 local_hendrb01 9893 May 24 07:30 quotations
-rwxrwxr-x. 1 local_hendrb01 local_hendrb01 1169 May 30 13:22 randquote.sh
Make sure the file permissions match.
The next decision is if you want the randquote script to run only when you login to the console, or both the console and the terminal.
If you want it to execute when logging a console only,
Edit the following file in your favorite editor.
/etc/profile
And the following lines.
##Display Random Quote On Login For All Users Console Login ONLY
## Added by Your Name / DATE
echo
/opt/randquote/randquote.sh
echo
Save the file.
We must now edit the following lines in our randquote program, since it is no longer residing in your standalone development directory.
Change line 18 to read:
QUOTATIONS=/opt/randquote/quotations
Change line 19 to read:
TEMP_QUOTATION=/opt/temp_quotation
Save the file, now logoff then back on and you should now the random quote generated.
If you also wish a random quote to be generated when you launch a shell from a terminal window in XWindows or from the console.
NOTE: If you put in both files, you will have 2 quotes generated when logging in from the console!
We must do the following.
Using your favorite editor, add the following lines to /etc/bashrc
##Display Random Quote when opening a shell session via the terminal For All Users
## Added by Your Name / DATE
echo
/opt/randquote/randquote.sh
echo
Save the file.
Open a terminal session.
If you only want specific users to have the random quotes displayed.
edit their respective .profile and .bashrc files in their home directory /home/<shortname>/
For our next tutorial we are going to do three things with this script!
1) Add it to a LINUX login profile, for both terminal and console login
2) Add it to a OS X login profile, for both terminal and SSH login
3) We are going to add something magical for our OS X users!
So be sure to come back for next month’s technical blog, as we do more with *NIX!
Special thanks go to Ken Pletzer and Jim Selleck for the wonderful work you did in the 90s with C-Net Amiga Professional BBS. For the many hours of fun I had with your product!
Errata in line 31 has been corrected. sed -e :a -e “s/^.\{1,${TERMWIDE}\}$/ &/;ta” -e ‘s/\( *\)\1/\1/’ TEMP+QUOTATION , has been replaced with the corrected “sed -e :a -e “s/^.\{1,${TERMWIDE}\}$/ &/;ta” -e ‘s/\( *\)\1/\1/’ $TEMP_QUOTATION”