With
./script.sh <filename
you attach the standard input of the script as a whole to the file filename
. This means that anything that reads from standard input in your script will read from the filename
file, until the end of that file is reached.
For example, a script that you would invoke in the above way, that simply changes all characters to upper-case, could be written as
#!/bin/sh
tr 'a-z' 'A-Z'
Note that filename
or <filename
is not an argument of the script, but an instruction to the shell to set up the script's standard input to come from the file.
On the other hand, if you ran the script using
./scripts.sh filename
then the name of the file would be available as $1
in the script and you would have to refer to that name when reading from the file:
#!/bin/sh
tr 'a-z' 'A-Z' <"$1"
or,
#!/bin/sh
filename=$1
tr 'a-z' 'A-Z' <"$filename"
This would allow you to parse the same file several times, whereas reading the contents through the standard input of the script would only allow you to read the file once (unless you saved it to a temporary file in the script, using e.g. cat >tmpfilename
, and then parsed that).
Giving the script filenames on the command line would also allow you to process any number of files in a loop:
#!/bin/sh
for pathname do
# code that processes "$pathname"
done