Due date: Monday, March 29, 2021.
In this lab we will write a bash CGI script that we will use to create a set of html files.
In this exercise we will write a bash script that generates an image gallery that displays a set of jpg images found in a folder.
Open a terminal and create a folder
called week9 in your folder c151. Go to that
folder. Copy the 4 jpg files that you worked on in Lab 7 Ex. 2, or
download them again from
here:
http://www.cs.iusb.edu/~dvrajito/teach/c151/fall.zip
and rename them as fall1.jpg, and so on.
Create a file called lab9.sh in any editor and start by
copying the content of the script simple_page.sh from Canvas
- Files - Week 9 into it.
This script creates the content of a simple html page displaying "Hello user". Since the script outputs the html content directly to the terminal, we'd have to use redirection to a file to create a file from it.
Change the title displayed on the page to "My Fall Pictures" or something along these lines.
This is the title that the script echoes as a heading 1 text.
Add the attribute align=\"center\" to the tag <h1> in the script so that the heading 1 title is centered on the page.
Here we are using the backslash in front of the quotes so that the quotes are displayed as characters in the text that is being output, because they need to be part of the html syntax the script produces.
Make the script executable with the command
chmod u+x lab9.sh
and then execute it by itself with the
command lab9.sh to see that the content is printed correctly.
Now we need to output the same thing to a file instead of the terminal.
Execute the command
lab9.sh > gallery.html
The file gallery.html should have been created.
Going back to the script file, add another echo command on a line before the last. On this line, output the tag <p> to start a new paragraph, and then add the same attribute to align it in the center that you used for the h1 tag. Make sure to leave a space between the tag name (p) and the attribute.
As you can see, instead of writing the html content directly into a file, we're making the bash script output it. The line you just wrote creates a new centered paragraph when executed.
Below it, add another echo command where you create a tag <img>. Inside this tag, add an attribute src=\"fall1.jpg\" or whatever the name of your image is. Then add another attribute (with a space before it) width=400 inside the same img tag.
So far this is the content of one html file showing one of your images.
Execute the script again like above.
If you open the resulting file gallery.html in a web browser, you should see a title and the image below it, both centered.
Now we would like to add a loop to this script that creates a separate html file for each image that we have in our folder. We would also like to supply the generic part name of the html files with an argument (such as "gallery"). So we'll also need a test for the script being run with at least one argument. In the script lab7b.sh that we created for week 7, we had such a loop and test.
Since some of you may not have completed Lab 7, add the
following lines to your script after the line #!/bin/bash/
and before everything else:
if [ $# -lt 1 ]
then
echo "The command should be executed with one argument"
else
i=1
for file in *.jpg
do
let i=$i+1
done
Then add a line containing
fi
at the end of the entire file.
So far we're using elements similar to the ones we used in the scripts in Lab 7.
Modify the error message at the beginning of the script to something appropriate for this lab.
For the purpose of creating links between the html pages that we create this way, we need to know how many of them there are. This way, we would not add a link forward for the last image.
Duplicate the entire loop, including the command i=1 preceding it, and paste right after it (before the echo messages). Move the line containing done after the echo commands.
What you should have now are two loops, the first one incrementing i without doing anything else, and the second one producing the html code. We want to convert the first loop into one counting the files.
In the first incarnation of the loop, change the variable i to a variable count everywhere, including the initialization before the loop. Then modify the initialization of count with 0 instead of 1.
This is all that the first loop will do: count the jpg files that we have. This way, we can compare the value of i in the first loop with the count when we create the links.
For the second loop, move the line where you increment i after all the echo commands but before the command done.
This way these commands are executed inside the loop, then the variable i is incremented. Indent all the echo commands with the tab.
Add an assignment inside this loop before all the echo commands:
htmlfile=$1$i.html
This declares the variable htmlfile that stores the name of the html file corresponding to the current jpg file with the number i in the name.
Replace the text fall1.jpg with "$file", extra quotes included.
This should close the string started with the first quote, follow it by the content of the variable $file,and then start a second string that goes to the end of the command line. This way, in each iteration, instead of displaying the file fall1.jpg, we display the current jpg file whose name can be found in the variable $file.
Now we would like to use redirection to the file $htmlfile in each echo command, so that instead of printing the html code to the terminal, it is stored in these files.
For the first echo command add
> $htmlfile
at the end. For each of the echo commands after that, add
>> $htmlfile
The simple redirection will erase the content of the file if it exists or start a new one if not every time it is run. The double greater version of the redirection does not erase the existing content of the file, if it exists, but appends (adds) the new content to it. This way, the first echo commands starts a new file, and all the subsequent ones add the content to the same file.
Going back to the terminal, run the command
lab9.sh gallery
This time we're not using gallery.html to redirect the output of the script. Instead, we're using the text gallery as argument to the script. Looking into the folder, you should now have the same number of html files as jpg files.
Open one of these files in a browser (or more) to check that the content is what we expect.
Let's create links between these html files. We will use the lower and greater signs to create these links, as image galleries often do.
Before the echo command that outputs
the <img tag, add these echo commands
echo "< "
echo $i "/" $count
echo ">"
echo "<br>"
These should have the effect of adding the < character followed by the image number out of the total (like "1/4" for 1 of 4), followed by the > sign. We will add the link to the previous image on the lower sign and the link to the next one on the greater sign. The <br> command breaks the line so that the image appears below this text.
Add the redirection to the file that we have on all the other echo commands to these too. Then save the script, go back to the terminal, and execute it again. Reload one of the pages in a browser to see if the effect is correct.
Now let's add a link to the lower sign (<).
Add an empty line before the echo command for
it. Add the following commands before:
if [ $i -gt 1 ] ; then
let j=$i-1
echo "<a href=\"$1$j.html\">" >> $htmlfile
and then indent them properly with a tab.
The first one tests is i is greater than 1, because we don't want to add a link to a previous image if the image is the first one in the folder. The second one declares a variable j and gives it the value of $i-1. The third line uses the value of j to create a link to the html file for the previous image in the folder.
After the echo command that displays the lower sign, add one echo command that output the tag </a> in the same way as all the others. Add one line after that containing only an else. Inside the else make a copy of the echo command that displays the lower sign by itself (the whole line for it and nothing else). Follow that with another line containing the command fi to end the conditional.
The idea is that if the image is the first one, then we want to display the lower sign without a link on it. That's the else case. The expression -gt in the conditional checks if the left side is larger than the right side of it.
Go back to the terminal and run the script again. Reload a couple of html files in the browser to check that the links were created correctly.
We also want to create links on the greater sign to the next image in the gallery.
Redo the whole operation for the command echoing the greater sign (>) to create links to the next image in the gallery. For that, after you duplicate the appropriate parts of the conditional, in the test replace [ $i -gt 1 ] with [ $i -lt $count ] (careful with the spaces to avoid errors).
This will return true if the variable i is less than the variable count because the last image should not have a link to one coming after it.
Then replace $i-1 with $i+1 in the assignment to link to the next image instead of the previous.
This should be all the changes that you need to do to the entire conditional.
Test the script again and check that the links are now complete and correct, and that the navigation through the set of html files work.
If the script works, then this is all you need to do for it.
Create an archive of the folder week9. For
this, in the terminal go to the folder above it. In that folder, do
the command
tar cfz lab9.tgz week9
Transfer the archive file to a local computer if you are
working remotely and either way, upload it to Canvas - Assignments -
Lab 9.
Upload to Canvas, in Lab 9, in Assignments, the tgz file you created at the end of the exercise, containing the week9 folder and all the files inside.