Addressing positinal parameters
Let's clear something up first: command-line arguments when referred to bash scripts are called "positional parameters", and that's variables like
$3 and so forth. That's the vocabulary I will be using here.
In accordance with proper shell syntax, positional parameters appear after command ( some might say duh, obviously, but syntax is important ):
command a b c
command is your script
my_script.sh. From script you could execute individual commands on parameters as
echo $1 and
echo $2. You can also work on all of them right away via for loop. So for example, your simple script could look as so:
# Note important difference between /bin/sh and /bin/bash
# for loop will substitute each $1, $2,$3 value into i each time
Addressing filename part
The fact that positional parameters can be anything - numbers or text - leaves interpretation of what that's supposed to be to the author of script. If string of text is filename then naturally it must exist somewhere on filesystems ( unlike anonymous files, pipes, or sockets [need citation here] ).
Let's say you call script as
my_script "this_is_my_file.txt". Simple way to test whetherthis_is_my_file.txt` is existing filename would be:
test -f "$1"
[ -f "$1" ]
$1 Because it's first positional parameter. Why
[ ? Because that's the same command. From there you can use it with either
if [ -f "$1" ]; then
echo "$1" exists
[ -f "$1" ] && echo "$1" exists
Of course, appropriate for a good script would be to issue an error if file doesn't exist and let the script quit with that.
One of the important things in scripting is developing your own habits. Because you cannot predict what filename your user will give to script, it could be anything, which also means it could start with
-. For example,
-afilename. Such filenames often break scripts and regular commands which have to deal with positional parameters. In case you expect or specifically require filename to exist in current working directory, it is a good idea to use
./ before variable.
if [ -f ./"$1" ]
Even if your user explicitly puts
./ this will work anyway:
$ test -f ././input.txt && echo "YES"
If we're dealing with filename that also includes path to file, that won't be a problem - the last slash before filename in
/path/to/-difficult_name.txt will separate filename from rest of the path.
...to be edited and expanded later...