Unix® Shell Programming读书笔记3

41.The . Command
There is a shell built-in command called . (pronounced "dot") whose general format is : . file
and whose purpose is to execute the contents of file in the current shell. That is, commands from file are executed by the current shell just as if they were typed at that point. A subshell is not spawned to execute the program. The shell uses your PATH variable to find file, just like it does when executing other programs.

42.exec command
exec can be used to close standard input and reopen it with any file that you want to read. To change standard input to file, you use the exec command in the form
exec < file
Any commands that subsequently read data from standard input will read from file.
Redirection of standard output is done similarly. The command
exec > report
redirects all subsequent output written to standard output to the file report.
To reassign standard input back to the terminal, you would write exec < /dev/tty
Note here that exec is not used to start up execution of a new program as normally described; here it is used to reassign standard input or standard output.
exec 2> /tmp/errors Here, all output to standard error will go to /tmp/errors.

43.The (...) and { ...; } Constructs
The first form causes the commands to be executed by a subshell, the latter form by the current shell.
If the commands enclosed in the braces are all to be typed on the same line, a space must follow the left brace, and a semicolon must appear after the last command:(cd bin; ls)
44.Another Way to Pass Variables to a Subshell
There's another way to do it besides setting the variable and then exporting it:Use a () to make it
eg.(DBHOME=/uxn2/data; DBID=452; export DBHOME DBID; dbrun)

45.${parameter}
If there's a potential conflict caused by the characters that follow the parameter name, you can enclose the name inside {}.

46.${parameter:-value}
This construct says to substitute the value of parameter if it is not null, and to substitute value otherwise.
+ do the opposite way.

47${parameter:=value}
This version is similar to the last, only f parameter is null; not only is value used, but it is also assigned to parameter as well (note the = in the construct). You can't assign values to positional parameters this way (that means that parameter can't be a number).A typical use of this construct would be in testing to see whether an exported variable has been set and, if not, setting it to a default value. ${PHONEBOOK:=$HOME/phonebook} This says that if PHONEBOOK is set to some value, leave it alone; otherwise, set it to $HOME/phonebook.
Note: use a ":" before it,and you need a null variable or something to make it run:
$ PHONEBOOK=
$ : ${PHONEBOOK:=$HOME/phonebook}
$ echo $PHONEBOOK See if it got assigned
/users/steve/phonebook

48.Pattern Matching Constructs
When you write the construct
${variable%pattern}
the shell looks inside variable to see whether it ends with the specified pattern. If it does, the contents of variable are substituted on the command line with the shortest matching pattern removed from the right.If you use the construct
${variable%%pattern}
the shell once again looks inside variable to see whether it ends with pattern. This time, however, it removes the longest matching pattern from the right. This is relevant only if the * is used in pattern. Otherwise, the % and %% behave the same way.The # is used in a similar way to force the pattern matching to occur on the left rather than the right. So, the construct.
${variable#pattern}
tells the shell to substitute the value of variable on the command line, with pattern removed from the left.Finally, the shell construct
${variable##pattern}
works like the # form, only the longest occurrence of pattern is removed from the left. eg.
$ var=testcase
$ echo $var
testcase
$ echo ${var%e} Remove e from right
testcas
$ echo $var Variable is unchanged
testcase
$ echo ${var%s*e} Remove smallest match from right
testca
$ echo ${var%%s*e} Remove longest match
te
$ echo ${var#?e} Remove smallest match from left
stcase
$ echo ${var#*s} Remove smallest match from left
tcase
$ echo ${var##*s} Remove longest match from left
e
$ echo ${var#test} Remove test from left
case
$ echo ${var#teas} No match
testcase

This method can be used to judge some postfix:
if [ ${file%.o} != $file ]
then
# file ends in .o
...
fi

49.${#variable}
This construct gives you the ability to count the number of characters stored inside a variable.
$ text='The shell'
$ echo ${#text}
9
50.The $0 Variable
The shell automatically stores the name of the program inside the special variable $0.

51.The set Command
The shell's set command is a dual-purpose command: it's used both to set various shell options as well as to reassign the positional parameters $1, $2, and so forth. 1)From the point that the set -x command is executed, all subsequently executed commands will be printed to standard error by the shell.You can turn off trace mode at any time by executing set +x
2)If words are given as arguments to set on the command line, those words will be assigned to the positional parameters $1, $2, and so forth. set is often used to "parse" data read from a file or the terminal.eg,this shell script:
#
# Count all of the words on standard input
#
count=0
while read line
do
set -- $line
count=$(( count + $# ))
done
echo $count
The -- option tells set not to interpret any subsequent arguments on the command line as options.

52.The IFS Variable
It stands for Internal Field Separator. The shell uses the value of this variable when parsing input from the read command, output from command substitution (the back-quoting mechanism), and when performing variable substitution.
You can change your IFS to any character or characters you want. This is useful when you want to parse a line of data whose fields aren't delimited by the normal whitespace characters.
Changing the IFS is often done in conjunction with execution of the set command:
$ line="Micro Logic Corp.:Box 174:Hackensack, NJ 07602"
$ IFS=:
$ set $line
$ echo $# How many parameters were set?
3
$ for field; do echo $field; done
Micro Logic Corp.
Box 174
Hackensack, NJ 07602
Taking advantage of changing the IFS,we will code a shell which can be used to count a file's number of line.
# Number lines from files given as argument or from
# standard input if none supplied (final version)
#
# Modify the IFS to preserve leading whitespace on input
IFS='
' # Just a newline appears between the quotes lineno=1
cat $* |
while read -r line
do
printf "%5d:%s\n" $lineno "$line"
lineno=$(( lineno + 1 )) done
Note:Because the IFS has an influence on the way things are interpreted by the shell, if you're going to change it in your program, it's usually wise to save the old value first in another variable (such as OIFS) and then restore it after you've finished the operations that depend on the changed IFS.

53.The readonly Command
The readonly command is used to specify variables whose values cannot be subsequently changed. For example,
readonly PATH HOME makes the PATH and HOME variables read-only.

54.The unset Command
Sometimes you may want to remove the definition of a variable from your environment. To do so, you type unset followed by the names of the variables.

55.The eval command
The shell takes care of pipes and I/O redirection before variable substitution, so it never recognizes the pipe symbol inside pipe.So does it for many operation.We use eval for scanning the command line twice
$ pipe="|" $ eval ls $pipe wc -l
The first time the shell scans the command line, it substitutes | as the value of pipe. Then eval causes it to rescan the line, at which point the | is recognized by the shell as the pipe symbol.
eval echo \$$# to display the last argument passed to it.
The eval command can also be used to effectively create "pointers" to variables:
$ x=100
$ ptrx=x
$ eval echo \$$ptrx Dereference ptrx
100
$ eval $ptrx=50 Store 50 in var that ptrx points to
$ echo $x See what happened
50

56.The wait Command
wait process-id
where process-id is the process id number of the process you want to wait for. If omitted, the shell waits for all child processes to complete execution. Execution of your current shell will be suspended until the process or processes finish execution. The shell stores the process id of the last command executed in the background inside the special variable $!. So the command wait $! waits for the last process sent to the background to complete execution: pid2=$! wait $pid2

57.The trap Command
trap commands signals
where commands is one or more commands that will be executed whenever any of the signals specified by signals is received.
If the command listed for trap is null, the specified signal will be ignored when received.
trap "rm $WORKDIR/work1.tmp $WORKDIR/dataout.tmp; exit" 2
So if the user interrupts execution of the program after this trap is executed, you can be assured that these two files will be cleaned up. The exit that follows the rm is necessary because without it execution would continue in the program at the point that it left off when the signal was received.This command is similar with the system-programming "interrupt-handler" defined by sigaction. If you wanted variable substitution to occur at the time that either signal 1 or 2 was received (for example, WORKDIR may not have been defined yet), you can put the commands inside single quotes: trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2
Executing trap with no arguments results in the display of any traps that you have changed.If you ignore a signal, all subshells also ignore that signal. However, if you specify an action to be taken on receipt of a signal, all subshells will still take the default action on receipt of that signal.
After you've changed the default action to be taken on receipt of a signal, you can change it back again with trap if you simply omit the first argument:trap 1

58.>&
Sometimes you may want to explicitly write to standard error in your program. You can redirect the standard output for a command to standard error by writing command >& 2 .The notation >& specifies output redirection to a file associated with the file descriptor that follows.
Frequently, you may want to collect the standard output and the standard error output from a program into the same file.
command >foo 2>>foo will do the work,You can also write command >foo 2>&1 to achieve the same effect; standard output is redirected to foo, and standard error is redirected to standard output (which has already been redirected to foo).
59.<&- and >&-
The characters >&- have the effect of closing standard output. The former one is designed to close standard input.

60.Functions
To define a function, you use the general format: name () { command; ... command; }
Note: They can't be passed down to subshells.Because the function is executed in the current shell, changes made to the current directory or to variables remain after the function has completed execution.
You can put definitions for commonly used functions inside your .profile so that they'll be available whenever you log in.
Alternatively, you can group the definitions in a file, say myfuncs, and then execute the file in the current shell by typing . myfuncs This has the effect of causing any functions defined inside myfuncs to be read in and defined to the current shell.
After a function has been defined, its execution will be faster than an equivalent shell program file. To remove the definition of a function from the shell, you use the unset command with the -f option.
If you execute an exit command from inside a function, its effect is not only to terminate execution of the function but also of the shell program that called the function. If you instead want to just terminate execution of the function, you can use the return command, whose format is return n

你可能感兴趣的:(unix,F#,读书,UP,Go)