Versions of read scripts
#!/bin/bash read line echo "$line"
This script contains a read from standard in followed by
and echo to standard out.
$ head -1 goodfile newfile ==> goodfile <== 1 1.8 head: cannot open `newfile' for reading: No such file or directory $ ./read1 <goodfile 1 1.8 $ ./read1 >newfile 1 2.2 $ head -1 newfile 1 2.2
After checking the first line of the files "goodfile" and "newfile", this demonstration
executes script by reading from goodfile and writing to the terminal, and
reading from the terminal and writing to the new file newfile. Notice
the leading spaces in the input do not apear in output.
read shell command will reads words or tokens from standard in.
Words are separated by a whitespace and the read is terminated by a new line character. Whitespace
is one or more spaces or tabs. The words are stored in the shell variables on the read command.
If there are more words than variables then all the remaining words, including all whitespace, will
be stored in the last token. A Backslash character \ may be used
to remove any special meaning to the following character, this is called backslash quoting.
There are three types of special characters for the read command:
head command will print the first few lines of a file.
With the option head -1 the command just prints the first line.
#!/bin/bash read -r x y etc echo "$x, $y"
This script will read the first two words of a line and echo them with as a comma separated pair. Any additional data on the line will be ignored.
$ ./read2 <goodfile 1, 1.8 $ echo 1 2 3 | ./read2 >file $ cat file 1, 2
This demonstrates executing script in the current working directory with the
same goodfile as above. The first command echos the first line with
commas separating the number, and the second uses the echo command
to show the extra 3 is ignored.
\ may be used in read input
to remove any special meaning to the following character, this is called backslash quoting.
There are three types of special characters for the read command:
-r option on the read command.
| sets up a pipe between two processes. In this
demonstration the stdout of the ./echo2 command is piped to the
stdin of the wc -l command. This illustrates a common
use of pipes - to avoid needing to write and then read an intermediate file.
#!/bin/bash
read -r x y etc
if [ -n "$etc" ]; then
echo "line too long" >&2
elif [ -z "$y" ]; then
echo "line too short" >&2
fi
echo $x${y:+, }$y
This script has two echo commands with one argument in double quotes.
The first is conditional on the variable figTitle containing data.
They are both preceded by a source command.
The file on the source command will contain variable assignment statements
for variables needed to construct the 3 or 4 gnuplot commands.
$ ./read3$ ./read3 1 line too short 1 $ echo 1 | ./read3 >file line too short $ cat file 1 $ echo 1 2 3 | ./read3 >file line too long $ cat file 1, 2
This demonstrates executing script in the current working directory with output
to the terminal window. The error message is because there is no file to source, and
following output shows the results of undefined variables. They are interpreted
as nulls (0 length strings). There are example files which can be used as a
run control file. The two commands cat commands
will copy an example file to the .echorc file and
display to contents. This way you can see the run control file and the resulting
output.
.echorc.
By sourcing the file these variable assignments, and will be available to
the original shell. The statements in a source
file are executed in the same environment as the original shell.
if... fi structureif test command begins an if/then structure, that
is terminated by the fi command. The then
is a separate command, and if it is on the same line you must separate
the commands with a ; character. Spaces are important
to make sure the commands a properly recognized by the parser.
[ -z "$myvar" ] evaluates as true if the myvar has
zero length or is undefined. [ -n "$myvar" ] evaluates as true
if the string is defined with content. The -n is optional, so just
a variable in double quote is a test for a string with data.
cat filenamecat command will read from standard in write each line to
standard out. When the output is redirected to a file this is just like the
cp command.
However, the cat command is more general. It can write to file, the
terminal or to a pipe.
#!/bin/bash
[ -r .echorc ] && source .echorc
case "$imageFile" in
*.png )
echo -n "\
set terminal png transparent size $imageWidth,$imageHeight
set output \"$imageFile\"
"
;;
*.svg)
echo -n "\
set terminal svg size $imageWidth $imageHeight dynamic
set output \"$imageFile\"
"
esac
echo -n "\
plot \"$dataFile\" with points pointtype 6${function_x:+, }$function_x
"
The source command is the second part of the compound command:
test command && source command
The test command [ -r .echorc ] evaluates as true if the file .echorc
is readable. The source .echorc is executed only as needed to determine
the truth value of the compound statement.
This script has two echo commands with one argument in double quotes. The
first is conditional on one of two cases that depend on the
pattern of the string in variable imageFile.
The second echo uses the alternate value expansion ${function_x:+, }. This expands
to ", " if the variable function_x has data and
null otherwise. This way there will be no dangling comma when the function is
not supplied, or is null.
$ ./echo4 plot "" with points pointtype 6 $ cat figrc | tee .echorc imageWidth=500 imageHeight=400 imageFile='fig.png' dataFile='fig.data' $ ./echo4 set terminal png transparent size 500,400 set output "fig.png" plot "fig.data" with points pointtype 6 $ cat fig1rc | tee .echorc imageWidth=500 imageHeight=400 imageFile='fig1.svg' dataFile='fig1.data' commandFile='fig1commands' function_x='0.83*2.046**x' figTitle='Data with fitted exponential' $ ./echo4 set terminal svg size 500 400 dynamic set output "fig1.svg" plot "fig1.data" with points pointtype 6, 0.83*2.046**x
The first example in figrc is written based on the
*.png pattern of the imageFile. Notice
that there is no dangling comma on the plot command. The
second example in fig1rc is written based on
the *.svg case. Notice that for format of the
commands are slightly different.
tee filenametee command will pipe everything for standard in to
standart out and copy the lines to the file on the command. In this
case we using it so the line being stored in the .echorc
file.
&& and || compound commands&& evaluation, the second command is skipped if
the first fails. (If the first fails the the compound command and fails and there
is not need to evaluate the second.) This a convient way to do one-line if
statement. With lazy || evaluation, the second command is skipped if
the first evaluates as true. (If the first is true the the compound command and true and there
is not need to evaluate the second.) This a convient way to do one-line unless
statement.
case... esac structurecase string command begins an case structure, that
is terminated by the esac command. The ( pattern
begins the individual cases. The commands up to the ;; are executed
if the string matches the pattern.
${myvar:-foo bar expands as $myvar if there is
data in it's value( not empty), or to "foo bar" otherwise. The string after the
":-" is the default value.${myvar:+foo bar expands as an empty string if there is
data in it's value( not empty), or too "foo bar" otherwise. The string after the
":-" is the alternate value.