Before processing, a path gets checked: does it exist, is it a file, can it be read. The check.sh script does such a check — see what it lets through.
In bash a condition goes in square brackets: [ -f "$f" ] means "$f is a regular file". The spaces after [ and before ] are required. if runs the commands after then when the condition is true, and otherwise the ones after else; fi closes the construct. check.sh tests every argument like this:
Check the files before processing
In ~/args-lab, check five paths with the check.sh script, then count the lines in three files with wc.
First, predict
check.sh prints OK when [ -f "$f" ] is true. Which paths get OK?
Now start the exercise, run the command and compare your prediction with the output.
-f answers one question — is this a regular file. An empty file and a root-owned file with mode 600 are both regular files, so both got OK. Other questions have other tests:
| Test | True when the path |
|---|---|
-e |
exists: a file, a directory — anything |
-f |
leads to a regular file |
-d |
leads to a directory |
-r |
is readable by whoever runs the script |
-s |
leads to a non-empty file |
-r looks at the permissions of whoever runs the script: student cannot read secret.txt, while root can. Several conditions at once are tested by bash's double-bracket form: [[ -f "$f" && -r "$f" && -s "$f" ]], where && means "and".
The script must filter out empty.txt but let notes.txt through. Which test do you use?
-
-dis true for a directory. notes.txt is a file, so this test filters it out as well. -
empty.txt exists, and
-eis true for it: the file passes just like notes.txt. -
empty.txt is readable: wc counted 0 lines in it.
[ -r empty.txt ]is true, so the file passes.
-s is true for a file larger than zero. empty.txt has not a single byte and notes.txt has two lines, so -s lets notes.txt through and stops empty.txt. You can try it in the terminal: if [ -s empty.txt ]; then echo yes; else echo no; fi prints no.