UNIX 新手指南: 一些很好的 Shell 诀窍( 五 )


脚本中的内联输入
在脚本中经常使用内联输入将使用信息输出到标准输出 。这通常通过将 here document 发送给 cat 来完成,如清单 12 中的脚本所示 。使用 vi 输入该脚本并保存到名为 baseconv 的文件中,并且将该文件设置为可执行文件(请参见创建 Shell 脚本部分) 。
清单 12. 使用 here document 提供 Shell 脚本使用信息
#!/bin/sh
cat << EOF
baseconv is a program to convert a number from one base to another.
Usage: baseconv [options]
Options:
-iBASE input base
-oBASE output base
-hdisplay this message
For more information, consult the baseconv man page.
EOF
当执行该脚本时,here document 的内容被发送到(使用 cat)标准输出 。立即尝试,如清单 13 中所示 。
清单 13. 从 here document 输出 Shell 脚本使用信息
$ baseconv
baseconv is a program to convert a number from one base to another.
Usage: baseconv [options]
Options:
-iBASE input base
-oBASE output base
-hdisplay this message
For more information, consult the baseconv man page.
$
此外,Bourne Shell 的大多数实现允许出现使用可选的连字符重定向的内联输入 。可选的连字符将所有的前导 Tab 字符从所有输入行的前面去掉,也包括包含限定字符串的行 。这对于您希望让编写的脚本保持当前缩进时会有帮助 。由于内联输入通常逐字读取,并且限定字符串必须在行的开始处给出,因此输入将打乱您的当前缩进并使脚本看起来不雅观 。因此,您可以重写清单 12 中的脚本,使其与清单 14 一致,而输出不会改变 。
清单 14. 带前导缩进的 Shell 脚本 here document
#!/bin/sh
cat <<- EOF
baseconv is a program to convert a number from one base to another.
Usage: baseconv [options]
Options:
-iBASE input base
-oBASE output base
-hdisplay this message
For more information, consult the baseconv man page.
EOF
在命令行使用内联输入
在命令行中,使用调用交互式程序的单命令行程序进行内联输入,比如在使用 bc 进制转换部分讨论的 bc 计算程序 。在任意交互式命令中,您可以使用 here document 代替实际文件,或代替任意行的实际输入 。
尝试使用 here document 将多行输入发送到 bc 。键入清单 15 中显示的内容 。
清单 15. 将内联输入发送到交互式程序
$ bc << EOF
> ibase=16
> A
> EOF
10
$
通常使用内联输入来扩展变量 。尝试清单 16 中显示的内容 。
清单 16. 内联输入如何扩展变量
$ BASECON=16
$ bc << EOF
> ibase=16
> $BASECON
> EOF
22
$
Subshell 执行
可以在一个名为 subshell 的新 Shell 中执行一个或一组命令,当前 Shell 是 SubShell 的父 Shell 。Subshell 继承父亲的环境 。I/O 重定向可以出现在子 Shell 和父 Shell 之间,但是 Subshell 永远不能修改父环境 。当您为了执行这些命令(比如设置变量)要更改 Shell 的环境,并且不想更改脚本自身运行所在的环境时,这就是您所期望的技术 。当您想要同时在后台启动多个长时间运行的进程时也最好使用 Subshell 。一个 Shell 可以生成多个 Subshell,而 Subshell 又可以循环生成属于它们自身的任意数量的 Subshell 。图 1 说明了这个过程 。
图 1. Subshell 如何与它的父 Shell 交互
Shell 有时自动生成自身的 Subshell,比如在管道中使用内置命令时 。在 Subshell 中,Shell $ 参数扩展到父 Shell 而不是 Subshell 的进程 ID (PID) 。
在 Subshell 中运行命令
要在 Subshell 中运行一组命令,可以使用括号将其括起来 。您可以使用重定向将输入发送到 Subshell 的标准输入,或将 Subshell 的集合输出发送到文件或管道 。

推荐阅读