Testing for File Characteristics

Problem

You want to make your script robust by checking to see if your input file is there before reading from it; you would like to see if your output file has write permissions before writing to it; you would like to see if there is a directory there before you attempt to cd into it. How do you do all that in bash scripts?

Solution

Use the various file characteristic tests in the test command as part of your if statements. Your specific problems might be solved with scripting that looks something like this:

#!/usr/bin/env bash
# cookbook filename: checkfile
#
DIRPLACE=/tmp
INFILE=/home/yucca/amazing.data
OUTFILE=/home/yucca/more.results

if [ -d "$DIRPLACE" ]
then
    cd $DIRPLACE
    if [ -e "$INFILE" ]
    then
        if [ -w "$OUTFILE" ]
        then
            doscience < "$INFILE" >> "$OUTFILE"
        else
            echo "can not write to $OUTFILE"
        fi
    else
        echo "can not read from $INFILE"
    fi
else
    echo "can not cd into $DIRPLACE"
fi

Discussion

We put all the references to the various filenames in quotes in case they have any embedded spaces in the pathnames. There are none in this example, but if you change the script you might use other pathnames.

We tested and executed the cd before we tested the other two conditions. In this example it wouldn’t matter, but if INFILE or OUTFILE were relative pathnames (not beginning from the root of the file system, i.e., with a leading “/”), then the test might evaluate true before the cd and not after, or vice versa. This way, we test right before we use the files.

We use the double-greater-than operator >> to concatenate output onto our results file, rather than wiping it out. You wouldn’t really care if the file had write permissions if you were going to obliterate it. (Then you would only need write permission on its containing directory.)

The several tests could be combined into one large if statement using the -a (read “and”) operator, but then if the test failed you couldn’t give a very helpful error message since you wouldn’t know which test it didn’t pass.

There are several other characteristics for which you can test. Three of them are tested using binary operators, each taking two filenames:

FILE1 -nt FILE2

Is newer than (it checks the modification date)

FILE1 -ot FILE2

Is older than

FILE1 -ef FILE2

Have the same device and inode numbers (identical file, even if pointed to by different links)

Table 6-2 shows the other tests related to files (see “Test Operators” in Appendix A for a more complete list). They all are unary operators, taking the form option filename as in if [ -e myfile ].

Table 6-2. Unary operators that check file characteristics

Option

Description

-b

File is block special device (for files like /dev/hda1)

-c

File is character special (for files like /dev/tty)

-d

File is a directory

-e

File exists

-f

File is a regular file

-g

File has its set-group-ID bit set

-h

File is a symbolic link (same as -L)

-G

File is owned by the effective group ID

-k

File has its sticky bit set

-L

File is a symbolic link (same as -h)

-O

File is owned by the effective user ID

-p

File is a named pipe

-r

File is readable

-s

File has a size greater than zero

-S

File is a socket

-u

File has its set-user-ID bit set

-w

File is writable

-x

File is executable

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.189.251