|

楼主 |
发表于 2005-11-1 12:08:39
|
显示全部楼层
在Bash的FAQ里找到这个:
- E4) If I pipe the output of a command into `read variable', why doesn't
- the output show up in $variable when the read command finishes?
- This has to do with the parent-child relationship between Unix
- processes. It affects all commands run in pipelines, not just
- simple calls to `read'. For example, piping a command's output
- into a `while' loop that repeatedly calls `read' will result in
- the same behavior.
- Each element of a pipeline, even a builtin or shell function,
- runs in a separate process, a child of the shell running the
- pipeline. A subprocess cannot affect its parent's environment.
- When the `read' command sets the variable to the input, that
- variable is set only in the subshell, not the parent shell. When
- the subshell exits, the value of the variable is lost.
- Many pipelines that end with `read variable' can be converted
- into command substitutions, which will capture the output of
- a specified command. The output can then be assigned to a
- variable:
- grep ^gnu /usr/lib/news/active | wc -l | read ngroup
- can be converted into
- ngroup=$(grep ^gnu /usr/lib/news/active | wc -l)
- This does not, unfortunately, work to split the text among
- multiple variables, as read does when given multiple variable
- arguments. If you need to do this, you can either use the
- command substitution above to read the output into a variable
- and chop up the variable using the bash pattern removal
- expansion operators or use some variant of the following
- approach.
- Say /usr/local/bin/ipaddr is the following shell script:
- #! /bin/sh
- host `hostname` | awk '/address/ {print $NF}'
- Instead of using
- /usr/local/bin/ipaddr | read A B C D
- to break the local machine's IP address into separate octets, use
- OIFS="$IFS"
- IFS=.
- set -- $(/usr/local/bin/ipaddr)
- IFS="$OIFS"
- A="$1" B="$2" C="$3" D="$4"
- Beware, however, that this will change the shell's positional
- parameters. If you need them, you should save them before doing
- this.
- This is the general approach -- in most cases you will not need to
- set $IFS to a different value.
- Some other user-supplied alternatives include:
- read A B C D << HERE
- $(IFS=.; echo $(/usr/local/bin/ipaddr))
- HERE
- and, where process substitution is available,
- read A B C D < <(IFS=.; echo $(/usr/local/bin/ipaddr))
复制代码 |
|