Lab Exercise - Functions

Shell functions are problematic. Because all variables are, by default, global. They tend to obscure, rather than clarify, any program. You should limit their use to well-defined tasks that have a tight interface. Ensure that all variables defined in a shell function are declared local to avoid polluting the namespace, and all information communicated between the caller and the function uses arguments.

Class Exercise

Write a function getfile that takes a prompt and a mode string. It asks the user for a filename by outputing the prompt and getting the path of a file. It then tests the file path to see if it is acceptable according to the mode string:

If the file path checks out, the path is output to stdout and the function returns a success status. If the file path or the mode string is invalid, the function must return a failure status and not output anything

All prompts and error messages must be output to stderr. The only thing output to stdout should be the file path.

Note: The goal of the function getfile is to be able to be used like this:

if ! ipfile=$(getfile "Enter the path to the input file" "r" ); then
    echo "Cannot get input file path" >&2
    exit 1

Boyd's program ftest does unit tests on your function. ftest includes getfile. To use this test script, set the directory's permissions to 700. Edit getfile to insert your code. The ftest program includes getfile from the current directory.

Note that you can test getfile yourself by including it and running it at command-line. Just use the dot operator to read the function into the current shell, then give it arguments and check its output and exit status. Below shows the inclusion of getfile, followed by two runs of the function asking for a readable file xyz. The first fails. The second succeeds.

$ . getfile 
$ getfile "Enter the path for the input file" "r" 
Enter the path for the input file (q to quit):xyz 
$ echo $? 
$ touch xyz # create the file path
$ getfile "Enter the path for the input file" "r" 
Enter the path for the input file (q to quit):xyz 
xyz # NOTE: this is getfile outputting the filename to stdout
$ echo $? 

Source Files:

ftest | getfile | getfile solution