Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: shell scripting basics

On May 23,  9:05am, Louis-David Mitterrand wrote:
} Subject: shell scripting basics
} - How to read standard input line-by-line inside a script?

The "read" command inputs a single line and assigns it to one or more
variables.  It returns (exits) nonzero (false) at end-of-file.

	while read line; do
	    something with $line
	while read word1 word2 word3 restofline; do
	    something with $word3
	    something with $word1
	    something with $restofline
	    something with $word2

} - How to store the output of a function in a scalar?
}     function hashcode() {
}         return $[$1 * $2]
}     }
}     scalar=`eval hashcode(param1, param2)`

There's a whole stack of misconceptions here.

First, defining a shell function is like creating a new command or script.
(A shell function really -is- a script, stored in memory rather than in a
disk file, except for a couple of special semantics.) 

So to execute a function, you write a line just as you would for any other

	hashcode param1 param2

Second, the "return" statement sets the exit code of the function; it's
just like calling "return(n)" from main() in a C program.  This is not
the way to produce "output" from the function.  A function's "output" is
whatever it writes to the standard output:

	function hashcode() {
	    print $[$1 * $2]

You could use "echo" instead of "print" if you prefer.  (Since there is
no "return" in that function, the exit code of the function is the exit
code of "print", which is normally 0 unless stdout is closed.)

What actually happens to the value when you use "return $[$1 * $2]" is
that it is put into the variable "$?", which always holds the exit code
of the most recent command.  Exit codes are used in conditionals like
"if" or "while" or in complex commands joined with "&&" or "||" to decide
the success (zero) or failure (nonzero) of the command.  (Thus in shell
scripts, zero is true and nonzero is false -- the opposite of C and many
other programming languages.)

When you use "return" you can only pass it a number; if you pass it any
other string, it's interpreted as zero (success).

Third, you almost never need "eval".  Simply:

	scalar=`hashcode param1 param2`

Or the preferred equivalent:

	scalar=$(hashcode param1 param2)

The only time you should use "eval" is when you want the same text to be
parsed twice (the usual once before "eval" is executed and then again
when "eval" executes it) before being interpreted as a command.  As an
example, you might do

	while read line; do
	    eval $line

to execute commands from the standard input (though there are much better
ways to do that, this is just a silly example).

Fourth, a function doesn't have to produce "output" in order to set a
scalar.  One of the special semantics of functions is that they run in
the current shell process with complete access to the shell's variables.
All variables are global unless you explicitly make them local.  So if
you wrote:

	function hashcode() {
	    scalar=$[$1 * $2]

Then following the command:

	hashcode 3 7

The variable "$scalar" is set to 21.  It's much more efficient to use the
global variable space when you can, because to capture the output of the
function using $(...) or `...`, the shell has to create a second process
with a new standard output (this second process then runs the function),
read that process's standard output, and wait for that process to exit.

If instead you wrote:

	function hashcode() {
	    local scalar
	    scalar=$[$1 * $2]

Then following any "hashcode" command the variable "$scalar" is set back
to its original value (or unset if it wasn't set to begin with).  It's
good practice to declare "local" any variables that the function doesn't
need to share with the calling shell.

Hopefully that's (perhaps more than) enough to get you going.  Have fun!

Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Messages sorted by: Reverse Date, Date, Thread, Author