Korn Shell Notes(V)

19. Input/Output Commands

19.1 Escape Characters



The /c escape character causes the trailing newline to be dropped from the output. It is often used to create prompts.
$ print "Enter choice: /c"
Enter choice: $
Notice that the command prompt was displayed following the argument, and not on the next line.

19.2 print Options


19.3 The exec Command

The execcommand is used to perform I/O redirection with file descriptors 0 through 9 using this format:
execI/O-redirection-command
The I/O redirection performed by the exec command stays in effect until specifically closed, changed, or if the script or shell terminates.
Here, file redir.out is opened as file descriptor 5 for reading and writing:
$ exec 5<>redir.out
Now the print command writes something to file descriptor 5:
$ print —u5 "This is going to fd 5"
and the cat command reads from it:
$ cat <&5
This is going to fd 5
To finish up, we use another exec to close file descriptor 5:
$ exec 5<&—

Standard input can be taken from a file like this:
exec 0<file
Commands could be read in from file, and it would be almost as if you typed them at your terminal.

19.4 The read Command

The read command is used to read input from a terminal or file. The basic format for the read command is:
readvariables
where a line is read from standard input. Each word in the input is assigned to a corresponding variable, so the first variable gets the first word, the second variable the second word, and so on. Here, "This is output" is read in to the variables X, Y, and Z. The first word of the input is This, so it is assigned to the first variable X. The second word is is, so it is assigned to the second variable Y. The third word is output, so it is assigned to Z.
$ print "This is output" | read X Y Z
$ print $X
This
$ print $Y
is
$ print $Z
output

If there aren't enough variables for all the words in the input, the last variable gets all the remaining words.
This command is the same as the last one, except that an extra string "again" is given.
$ print "This is output again " | read X Y Z
$ print $X
This
$ print $Y
is
$ print $Z
output again


19.4.1 Reading Input from Files

The read command by itself will only read one line of input, so you need a looping command with it. To read in the contents of a file, use this format:
exec 0<file
while read
variable
do
commands
done

The exec command opens file for standard input, and the while command causes input to be read a line at a time until there is no more input.

Here is an alternate format that will also work for reading input from files:
catfile| while readvariable
do
commands
done

On the systems tested, the exec format for reading input from files was about 40-60 times faster than the last version above.

19.4.2 The IFS Variable

The read command normally uses the IFS (Internal Field Separator) variable as the word separators. The default for IFS is space, tab, or snewline character, in that order, but it can be set to something else.
By setting IFS to :, the fields in the /etc/passwd file could be read into separate variables.
$ cat ifs_test
IFS=:
exec 0</etc/passwd
while read -r NAME PASS UID GID COMM HOME SHELL
do
print "Account name= $NAME
Home directory= $HOME
Login Shell= $SHELL"
done

19.4.3 Reading Input Interactively

The read command allows input to be read interactively using this format:
readname?prompt
where
promptis displayed on standard error and the response is read intoname.

So instead of using two commands to display a prompt and read the input:
$ print —n "Enter anything: "
$ read ANSWER
The same thing can be done with one command.
$ read ANSWER?"Enter anything: "
Enter anything: ANYTHING
Here is ANSWER:
$ print $ANSWER
ANYTHING

19.4.4 TheREPLYvariable

If no variables are given to thereadcommand, the input is automatically assigned to theREPLYvariable. Here, ANYTHING is read into REPLY:
$ print ANYTHING | read
$ print $REPLY
ANYTHING

20 Miscellaneous Programming Features

20.1 The . Command

The.command reads in a complete file, then executes the commands in it as if they were typed in at the prompt. This is done in the current shell, so any variable, alias, or function settings stay in effect. It is typically used to read in and execute a profile, environment, alias, or functions file. Here the .profile file is read in and executed:
$ . .profile

The following example illustrates the difference between executing files as Korn shell scripts and reading/executing them using the .command. The .test file sets the variable X:
$ cat .test
X=ABC
When the .test file is executed as a Korn shell script, variable X is not defined in the current environment, because scripts are run in a subshell:
$ ksh .test
$ print $X
$
After the .test file is read in and executed using the . command, notice that the variable X is still defined:
$ . .test
$ print $X
ABC
The standard search path, PATH, is checked if the file is not in the current directory.

20.2 Functions

Functions are most efficient for commands with arguments that are invoked fairly often, and are defined with the following format:

functionname{
commands
}

To maintain compatibility with the Bourne shell, functions can also be declared with this POSIX-style format:
function-name(){
commands
}

These types of functions have many limitations compared to Korn shell style functions, such as no support for local variables.

20.3 Scope & Availability

By default, functions are not available to subshells. This means thata regular function that was read in your working environment,.profilefile, or environment file would not be available in a Korn shell script.

To export a function, use thetypeset -fxcommand:
typeset -fxfunction-name

To make a function available across separate invocations of the Korn shell, include the
typeset -fxfunction-namecommand in the environment file.

20.4 Function Variables

All function variables, except those explicitly declared locally within the function with thetypesetcommand, are inherited and shared by the calling Korn shell script. In this example, the X, Y, and Z variables are set within and outside of the function f:

$ cat ftest
X=1
function f {
Y=2
typeset Z=4
print "In function f, X=$X, Y=$Y, Z=$Z"
X=3
}
f
print "Outside function f, X=$X, Y=$Y, Z=$Z"

Notice that when executed, all the variable values are shared between the function and calling script, except for variable Z, because it is explicitly set to a local function variable using the typeset command.
The value is not passed back to the calling Korn shell script:
$ ftest
In function f, X=1, Y=2, Z=4
Outside function f, X=3, Y=2, Z=

The current working directory, aliases, functions, traps, and open files from the invoking script or current environment are also shared with functions.

20.5 Displaying Current Functions

The list of currently available functions are displayed using thetypeset -fcommand.

20.6 Autoloading Functions

To improve performance, functions can be specified to autoload.This causes the function to be read in when invoked, instead of each time a Korn shell script is invoked, and is used with functions that are not invoked frequently. To define an autoloading function, use thetypeset -fufunction-namecommand. Here, lsf is made an autoloading function:
$ typeset —fu lsf

Theautoloadalias can also be used to define an autoloading function. On most systems, it is preset totypeset -fu.

TheFPATHvariable which contains the pathnames to search for autoloading functions must be set and have at least one directory for autoloading functions to work.

20.7 Discipline Functions

Discipline functions are a special type of function used to manipulate variables. They are defined but not specifically called. Rather, they are called whenever the variable associated with the function is accessed.

There are some specific rules as to how discipline functions are named and accessed. First of all, discipline functions are named using this syntax:
name.function

Notice the the funcion has two parts separated with a dot.The first part name corresponds to the name of a variable, and the second part must beget,set, orunset. These correspond to the following operations on the variable:
  • get whenever the base discipline variable is accessed
  • set whenever the base discipline variable is set
  • unset whenever the base discipline variable is unset

For example, the discipline function LBIN.get, LBIN.set, LBIN.unset is called whenever the variable LBIN is accessed, set, or unset.

All three discipline functions are optional, so not all need to be specified. Within a discipline function, the following special reserved variables can be used:
  • .sh.name name of current variable
  • .sh.value value of the current variable
  • .sh.subscript name of the subscript (if array variable)

From a practical perspective, discipline functions are often used to help debug by tracing the setting and current value of variables in running scripts. Here is a function that can be used to trace setting the value of X:
function X.set {
print "DEBUG: ${.sh.name} = ${.sh.value}"
}

Discipline functions are also a good place to centralize your variable assignment validation rules. Here is a function that checks to make sure that X it set ao a number between 3 and 10:
function X.set {
if (( .sh.value<3 || .sh.value >10 ))
then
print "Bad value for ${.sh.name}: ${.sh.value}"
fi
}

Note thatbuiltinfunctions can also be used as additional discipline functions.

20.8 FPATH

TheFPATHvariable contains a list of colon-separated directories to check when an autoloading function is invoked. It is analogous toPATHandCDPATH, except that the Korn shell checks for function files, instead of commands or directories. Each directory in FPATH is searched from left-to-right for a file whose name matches the name of the function. Once found, it is read in and executed in the current environment. With the followingFPATHsetting, if an autoloading functionlsfwas invoked, the Korn shell would check for a file calledlsfin/home/anatole/.fdir, then/etc/.functions, and if existent, read and execute it:

$ print $FPATH
/home/anatole/.fdir:/etc/.functions

There is no default value forFPATH, so if not specifically set, this feature is not enabled.

20.9 Removing Function Definitions

Functions are removed by using theunset -fcommand. Here, the rd function is removed:
$ unset -f rd

20.10 Traps

The trap command is used to execute commands when the specified signals are received.
trapcommands signals

Trap commands are useful in controlling side effects from Korn shell scripts. For example, if you have a script that creates a number of temporary files, and you hit the <BREAK> or <DELETE> key in the middle of execution, you may inadvertently leave the temporary files. By setting atrapcommand, the temporary files can be cleaned up on an error or interrupt.

Thetrap_testscript creates some files, then removes them when an interrupt is received.Notice that thetrapcommand is surrounded in single quotes. This is so that theFILESvariable is evaluated when the signal is received, not when the trap is set.
$ cat trap_test
trap 'print "$0 interrupted - removing temp files" ;/
rm —rf $FILES; exit 1' 1 2
FILES="a b c d e f"
touch $FILES
sleep 100
$ trap_test
Ctl-c
trap_test interrupted - removing temp files

If an invalid trap is set, an error is generated.

20.10.1 Ignoring Signals

Thetrapcommand can be used to ignore signals by specifying null as the command argument:
trap ""signals
This could be used to make all or part of a Korn shell script uninterruptable using normal interrupt keys like Ctl-c.

20.10.2 Resetting Traps

The trap command can also be used to reset traps to their default action by omitting the command argument:
trap-signals
or
trapsignals

20.10.3 Exit & Function Traps

A trap can be set to execute when a Korn shell script exits. This is done by using a 0 or EXIT as the signals argument to the trap command:
trap'commands'0
or
trap'
commands'EXIT
This could be used to consolidate Korn shell script cleanup functions into one place.

20.10.4 Trap Signal Precedence

If multiple traps are set, the order of precedence is:
  • DEBUG
  • ERR
  • Signal Number
  • EXIT

20.10.5 Trapping Keyboard Signals

The Korn shell trapsKEYBDsignals (sent when you type a character) and automatically assigns the following reserved variables:
  • .sh.edchar contains last character of key sequence
  • .sh.edtext contains current input line
  • .sh.edmode contains NULL character (or escape character is user in command mode)
  • .sh.edcol contains position within the current line

20.11 Debugging Korn Shell Scripts

The Korn shell provides a number of options that are useful in debugging scripts:noexec,verbose, andxtrace. The noexec option causes commands to be read without being executed. It is used to check for syntax errors in Korn shell scripts. The verbose option causes the input to be displayed as it is read. The xtrace option causes the commands in a script to be displayed as they are executed.

20.11.1 Debugging with trap

The trapcommand can also be helpful in debugging Korn shell scripts. The syntax for this type of trap command is:
trap commands DEBUG
or
trap commands ERR



20.12 Co-Processes

Co-processes are commands that are terminated with a|&character. They are executed in the background, but have their standard input and output attached to the current shell. The print -pcommand is used to write to the standard input of a co-process, while read -pis used to read from the standard output of a co-process. Here, the output of the date command is read into the DATE variable using the read -p command:
$ date |&
[2] 241
$ read —p DATE
$ print $DATE
Thu Jul 18 12:23:57 PST 1996
Co-processes can be used to edit a file from within a Korn shell script.
THE END

你可能感兴趣的:(shell)