Flylib.com

Books Software

 
 
 

Retrieving Output From Functions


Retrieving Output From Functions

Functions cannot modify the arguments that are passed to them. There are two ways to return output from a function. One way is to modify global variables , like this:

lastchar() {
  local length=${#1}
  if [ $length -gt 0 ]
      then clast=$(echo   cut -c $length)
  else
      clast=''
  fi
}

The lastchar function in this example copies the last character of the first argument into global variable clast . Since clast is not defined within the function, it is global and may be referenced outside of the function.

The other common way to retrieve data from a function is to write to stdout . You can use the command-substitution technique to direct the output to a variable. This is shown in Figure 13.14. The lcname function writes the lowercase equivalent of an argument to standard output. The command substitution forces the output into variable varx .

start figure


function lcname { echo   tr '[:upper:]' '[:lower:]' ; }


/home/jsmith $


varx= "Joe Smith"


/home/jsmith $


echo $varx


Joe Smith


/home/jsmith $


varx=$(lcname "Joe Smith")


/home/jsmith $


echo $varx


joe smith


/home/jsmith $

end figure

Figure 13.14: Functions can return data to calling routines by writing to stdout.



Summary

A Qshell function is like a subroutine, function, or procedure in other languages. Functions are defined within a process, so they execute more quickly than external files. Like functions and subroutines in other languages, functions promote modularity in Qshell scripts. Functions may contain local variables and receive parameters. Functions may be defined using the Bourne-shell syntax or the newer Korn-shell syntax. Like scripts, built-in utilities, and internal commands, functions are invoked by typing their names .



Chapter 14: Path - Name Expansion

Before Qshell interprets a command or passes arguments to a utility, it examines the command string for special characters called wildcards and replaces expressions with lists of file names . This process is formally known as path-name expansion but is commonly called globbing . Globbing gives you an easy way to work with groups of files while writing only a little bit of code.

It is important to understand that globbing is something Qshell does, not something that Qshell commands do. Qshell commands, whether scripts or utilities, just see the results of globbing. (Contrast this behavior to that of MS-DOS, which requires that the individual commands process wildcards for themselves .)

Globbing

Qshell could not glob were it not for metacharacters, also known as wildcards. Metacharacters are characters that represent other characters. For example, the letter a and the digit 5 are not metacharacters. They cannot represent other characters. The question mark, however, is a metacharacter because it can match any character. The globbing metacharacters are listed in Table 14.1.

Table 14.1: Metacharacters Used in Globbing

Character

Description

*

Matches zero or more characters

?

Matches exactly one character

[ ]

Matches ranges or groups of characters

!

Negates a group or range of characters

\

Escapes (disables) the metacharacter that follows it

The following example shows the use of the asterisk metacharacter:

print *

arglist.qsh bin bu.qsh casemon.qsh caseqtr.qsh casewild.qsh data.ascii
data.ebcdic donde.qsh echoprocess.qsh edity.txt ftpmodel.txt
goodoleboys.txt helpme mydata.csv myfile.txt myscript.qsh protos.jar
protos.savf qsh_trace read002.qsh select01.qsh temp.txt test1.txt
test1a.txt theirscript.qsh tscript.qsh upper.txt

Before executing the print utility, Qshell replaces the asterisk with a list of the files in the current directory.

An example of the question-mark metacharacter is shown here:

ls -dF ???

x.2*    x.y     bin/

The ls command displays the names of files with three-character names. The d option prevents the display of the contents of subdirectories. The F option appends a slash (/) to the end of directory names, an asterisk (*) to the end of executable file names, and an at sign (@) to the end of the names of symbolic links.

Globbing is case-sensitive. The following command uses the asterisk to copy all files whose names begin with a lowercase c to directory temp1:

cp c* temp1

Using Metacharacters with a Script

You can get a better feel for globbing by writing a shell script that prints the positional parameters. Such a script is listed in Figure 14.1, where it is named listargs.qsh.

start figure

# script name: listargs.qsh
#
declare -i argnbr=0
print "Number of arguments: $#"
while [ "" ]
   do
      let argnbr=argnbr+1
      printf "%3d (%s)\n" $argnbr ""
      shift
   done

end figure

Figure 14.1: The listargs.qsh script shows the effects of globbing.

The following example shows how the listargs.qsh script works without any globbing. Notice that Qshell has preserved the blanks in quoted strings.


listargs.qsh Qshell rulz "Qshell rulz" 'Qshell rulz' "Qshell rulz"


Number of arguments: 5


1 (Qshell)


2 (rulz)


3 (Qshell rulz)


4 (Qshell rulz)


5 (Qshell rulz)

Running listargs.qsh with various globbing expressions shows you what Qshell does to the metacharacters before passing control to a script. In the first use of globbing with listargs.qsh, Qshell expands the *.txt expression into a list of all files that end with a period followed by txt:


listargs.qsh *.txt


Number of arguments: 8


1 (edity.txt)


2 (ftpmodel.txt)


3 (goodoleboys.txt)


4 (myfile.txt)


5 (temp.txt)


6 (test1.txt)


7 (test1a.txt)


8 (upper.txt)

Since there are eight .txt files in the current directory, the listargs.qsh script runs as if the user had entered the eight file names as arguments.

The next example expands the globbing expression into a list of all file names that have an e as the second character:


listargs.qsh ?e*


Number of arguments: 7


1 (helpme)


2 (read002.qsh)


3 (select01.qsh)


4 (temp.txt)


5 (temp1)


6 (test1.txt)


7 (test1a.txt)

In a slightly more complex example, you can use globbing to expand the expression into a list of files whose names begin with either an h or an r :


listargs.qsh [hr]*


Number of arguments: 2


1 (helpme)


2 (read002.qsh)

The following globbing expression illustrates a range of file names:


listargs.qsh [d-g]*


Number of arguments: 7


1 (data.ascii)


2 (data.ebcdic)


3 (donde.qsh)


4 (echoprocess.qsh)


5 (edity.txt)


6 (ftpmodel.txt)


7 (goodoleboys.txt)

All files whose names begin with any letter from d to g are listed. Globbing can also have the opposite effect, for example, listing files whose names do not begin with a letter in the range d to t :


listargs.qsh [!d-t]*


Number of arguments: 11


1 (arglist.qsh)


2 (bin)


3 (bu.qsh)


4 (casemon.qsh)


5 (caseqtr.qsh)


6 (casewild.qsh)


7 (upper.txt)


8 (while001.qsh)


9 (x.2)


10 (x.y)


11 (yourscript.qsh)

Finally, here is a fairly complex use of metacharacters:


listargs.qsh [d-t][eiy][i-m]*


Number of arguments: 6


1 (demo.csh)


2 (helpme)


3 (select01.qsh)


4 (tema)


5 (temp.txt)


6 (temp1)

Qshell includes filenames that begin with any letter between d and t , followed by an e , i , or y , followed by any letter from i to m , followed by zero or more characters.

Unmatched Expansion Expressions

If no filenames match the expansion pattern, Qshell passes the unmodified expression to the utility or script, as shown here:


echo x*x*


x*x*


/home/jsmith $



echo e*e*



echoprocess.qsh

There are no files in the current directory whose names begin with an x and have another x in the file name, so the first echo displays the argument as it was keyed. However, the second echo is expanded because there is one file whose name begins with an e and has an embedded e .

Globbing and Case-insensitive File Systems

In some case-insensitive file systems, letters used in patterns must be in uppercase. This is especially applicable to the qsys.lib (library) file system. (Although the qsys.lib file system is case insensitive, it stores object names in uppercase.) When using globbing for the library file system, be sure to use uppercase letters in the pattern, as shown in Figure 14.2. The first time listargs.qsh runs, the expression in parameter 1 is passed unmodified to the script. However, the second time listargs.qsh runs, the expression is globbed into four file names.

start figure

{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}


listargs.qsh /qsys.lib/smith.lib/*.pgm


Number of arguments: 1


1 (/qsys.lib/smith.lib/*.pgm)


/home/jsmith $


listargs.qsh /qsys.lib/smith.lib/*.PGM


Number of arguments: 4


1 (/qsys.lib/smith.lib/EDITX.PGM)


2 (/qsys.lib/smith.lib/MON001.PGM)


3 (/qsys.lib/smith.lib/MONEVAL4.PGM)


4 (/qsys.lib/smith.lib/MONEVAL5.PGM)

end figure

Figure 14.2: When globbing is used with the library system, wildcard expressions must be in uppercase letters.