- 论坛徽章:
- 1
|
kornshell Frequently Asked Questions[3]
III.SHELL PROGRAMMING QUESTIONS
Q1.What is the difference between * and @, for example, and ?
A1.When used outside of "", they are equivalent. However, within
double quotes, "$@" produces one argument for each positional
parameter, and "$* produces a single argument. Note that "$@"
preserves arguments lists, whereas $* may not unless both
word splitting and pathname expansion are disabled.
Q2.Why do I need spaces around { and } but not around ( and )?
A2.The characters ( and ) are shell metacharacters and are always
treated specially. For historical reasons, { and } were
treated as reserved words and are only special as separate
words at locations in which a command can begin.
Q3.How do I get read to maintain the characters?
A3.Use read -r instead.
Q4.How can a write a ksh script that responds directly to each
character so that you user just has to enter y, not y<return>?
A4.There are two ways to do this. The easiest is to use
- read -n1 x
- Alternatively, you could do
- function keytrap
- {
- .sh.edchar=${sh.edchar}$'n'
- }
- trap keytrap KEYBD
- and then
- read x
复制代码
Q5.What is the purpose of $'...'?
A5.The $'...' option was added to ksh93 to solve the problem
of entering special characters in scripts. It uses
ANSI-C rules to translate the string between the '...'.
It would have been cleaner to have all "..." strings handle
ANSI-C escapes, but that would not be backwards compatible.
Q6.What is the -n option used for?
A6.You should always run ksh -n on each script you write. The -n
option will check for syntax errors on paths that might not
even be checked when you run the script. It also produces
a number of warning messages.
Q7.Why are both `...` and $(...) used for command substitution?
A7.The `...` method has some rather strange quoting rules
and does not nest easily. $(...) was added to ksh88 to
make command substitution easy to use. `...` is provided
for backwords compatibility only.
Q8.How can I tell if all the commands of a pipeline have succeeded?
A8.The pipefail option was added to the 'g' point release of ksh93.
With pipefail set, a pipeline will fail if any element of the
pipeline fails. The exit status will be that of the first
command that has failed.
Q9.How do I connect to a socket from a shell script?
A9.exec 3<> /dev/tcp/hostname/portnum
will open a tcp connection to portnum on hostname for
reading and writing on file descriptor 3. You can then
use read and print statements with file descriptor 3,
or redirection operators <&3 or >&3 to use these connections.
Q10.What is the difference between [...] and [[...]]?
A10.The [[...]] is processed as part of the shell grammar
whereas [...] is processed like any other command.
Operators and operands are detected when the command is
read, not after expansions are performed. The shell does not
do word splitting or pathname generation inside [[...]].
This allows patterns to be specified for string matching
purposes.
Q11.How come [[ $foo == $bar ]] is true and [[ $bar == $foo ]] is false?
A11.The == operator is not symmetrical. It takes a string on the left
and a pattern on the right. However, if you double quote the right
hand side, which removes the special meaning of pattern match
characters, then this becomes a string comparison so that
[[ "$foo" == "bar" ]] and [[ "$bar" == "$foo" ]] are equivalent.
Q12.Why does have print since echo already exists is is widely used?
A12.The behavior of echo varies from system to system.
The POSIX standard does not define the behavior of echo when
the first argument beings with a - or when any argument
contains a character. This makes echo pretty useless for
use in portable scripts.
Q13.What is $bar after,echo foo | read bar?
A13.The is foo. ksh runs the last component of a pipeline
in the current process. Some shells run it as a subshell
as if you had invoked it as echo foo | (read bar).
Q14.What is the difference between ((expr)) and $((expr))?
A14.((expr)) is a command that evaluates an arithmetic expression.
The exit status of this command is 0 if the expression
evaluates to non-zero and is 1 if it evaluates to 0.
0 is an string expansion that expands to a string
representation of the value of this arithmetic expression.
It can be used anywhere a variable substitution is premitted.
Q15.What is the difference between $((x*y)) and $(($x*$y))?
A15.In the first case the value of x and the value of y are multiplied
together, and then their result is converted to a string. In the
second case variables $x, *, and $y are concatenated to form
an arithmetic expression which is then evaluated. This can
yield different results, for example,
- x=2+3 y=4+5
- print $((x*y)) $(($x*$y))
- 45 19
复制代码
Q16.How do I handle filenames with spaces in them?
A16.To be POSIX conforming, ksh has to do word splitting and
pathname expansion the results of substitutions. You can
enclose variable substitutions in "..." to prevent both
word splitting and pathname expansion. Alternatively,
you can disable word splitting by setting IFS='' and
pathname generation with set -o noglob.
Q17.What are active variables?
A17.By default shell variables are passive. They hold values
given to them on assignment, and return values on reference.
Active variables allow the assignment and reference (and
other actions) be controlled by functions specific to that
variable. At the shell level, a 'get', 'set', or 'unset'
shell function can be defined for any variable to make them
active, so that the function foo.set will be invoked whenever
the variable foo is assigned a value. At the C interface
level, several functions can be stacked together for an
active variable.
Q18.What is the difference between function name and name()?
A18.In ksh88 these were the same. However, the POSIX standard
choose foo() for functions and defined System V Release 2
semantics to them so that there are no local variables
and so that traps are not scoped. ksh93 keeps the ksh88
semantics for functions defined as function name, and
has changed the name() semantics to match the POSIX
semantics. Clearly, function name is more useful.
Q19.What are name reference variables and how are they used?
A19.Reference variables are variables in which all references
and assignments refer to the variable that they reference.
For example,
typeset -n name=$1
name=value
is equivalent to
eval $1='value'
References are most useful for passing arguments such as
arrays to functions.
Q20.If i=1 and var1=some value, how do I print vartt to get its value?
A20.Either use
- eval print var$i
- or
- typeset -n x=var$i
- print $x
复制代码
Q21.How can I shift the elements of an array?
A21.The shift special builtin-command only works for positional
parameters. However, noting that array subscripts start at 0,
you can use
set -A name "${name[@]:1}"
to shift the array.
Q22.Why are the braces required with array references, e. g. ${x[1]}?
A22.It would be nice to do $x[1], but the POSIX shell would expand $x
and then search for the file pattern resulting by concatenating [1].
ksh is POSIX compatible.
Q23.How do I get the list of subscript names for an associative array?
A23.The prefix operator ! in variable expansions can be used to
get names. To get the names of subscripts for an array, associative
or indexed, use ${!var[@]}.
Q24.How do I do global substitutions on the contents of shell variables?
A24.Use // instead of / for global substitution, ${var//aa/bb} will
expand to the value of with each "aa" replace by "bb".
Q25.How can I convert %XX values to ascii?
A25.You can convert this to a sequence of ANSI C strings and then eval that
string, for example suppose the variable 'foo' contains %XX strings,
then
- eval print -r -- "$'${foo//'%'@(??)/'x1"'$'"}'"
复制代码 will print out the string in ascii.
Q26.I want to use exec to open a file. How do I prevent the script from exiting if the exec fails?
A26.If you run
command exec ... || error ...
then error will be executed if the exec fails, but the script
will not terminate. The command builtin will prevent the shell
from exiting when special built-ins fail.
Q27.How do I execute a builtin inside a function of the same name?
A27.You use the command builtin for this. For example,
- function cd
- {
- command cd "$@" && title "$PWD"
- }
复制代码
will run the builtin command cd from within the function cd
rather than calling the function cd recursively.
Q28.How are variables scoped in ksh?
A28.The scoping of variables was not defined for ksh88 but in ksh93
static scoping was specified. For example the output from
- function f1
- {
- print foo=$foo
- }
- function f2
- {
- typeset foo=local
- f1
- }
- foo=global
- f2
复制代码
will be "global". To get f2 to cause f1 to print the local
value of foo, f2 can run "foo=$foo f1" instead.
Q29.Can you write a self reproducing program in KornShell?
A29.Yes, the following program is self reproducing. Any shorter ones?
- n="
- " q="'" x="cat <<-!" y=! z='n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$y'
- cat <<-!
- n="$n" q="$q" x="$x" y=$y z=$q$z$q$n$x$n$z$n$y
- !
复制代码
=====================================================
[ 本帖最后由 寂寞烈火 于 2005-11-20 18:59 编辑 ] |
|