第 15 章 BASH Shell
Linux 下 主 要 有 三 种 不 同 的 Shell :Bourne Again She l(l BASH ),Public Korn
Shel l( PDKSH )及 TCSH Shell 。这些 Shell 都 是 相 应 UNIX 下 Shell 的 增 强 版 。BASH Shell 是 UNIX 下 的 Borune Shell 的 增 强 版 , 它 包 括 了 Korn Shell 和 C Shell 的 大 多 数 高 级 特 性 。 TCSH Shell 是 C Shell 的 增 强 版 , 而 C Shell 最 初 是BSD 版 UNIX 系 统 下 开 发 的 一 种 Shell。 PDKSH 是 UNIX 系 统 下 Korn Shell 的子 集 。 尽 管 这 些 UNIX 系 统 下 的 Shell 有 较 大 的 区 别 , 但 它 们 仍 然 有 许 多 共 同 的特 性 。 虽 然 UNIX 系 统 中 Bourne Shell 缺 乏 其 它 UNIX 版 本 下 Shell 的 许 多 功能 , 但 在 Linux 中 , BASH Shell 同 时 具 有 Korn Shell 、 C Shell 及 TCSH Shell 的 大 多 数 高 级 特 性 。
在 Lunix 系 统 中 ,所 有 以 上 三 种 Shell 你 都 可 以 使 用 ,但 其 缺 省 Shell 是 BASH Shell 。本 章 中 所 有 的 例 子 都 是 使 用 的 BASH Shell 。当 你 登 陆 进 入 Lunix 系 统 后 , 系 统 将 采 用 缺 省 Shell , 但 你 可 以 转 换 到 另 一 种 Shell 下 : 键 入 tcsh , 系 统 将 使用 TCSH Shell ; 键 入 bash , 系 统 将 使 用 BASH Shell 。 你 可 以 用 CTR L + d 或者 用 exit 命 令 退 出 一 种 Shell。
在 使 用 Lunix 系 统 的 过 程 中 ,你 可 以 只 使 用 一 种 Shell 完 成 你 所 要 做 的 工 作 。本 书 第 5 章 讨 论 了 所 有 Shell 的 一 般 特 性 , 而 本 章 及 下 一 章 将 讨 论 BASH Shell 及 TCSH Shell 。 本 书 不 讨 论 PDKSH Shell , 因 为 PDKSH Shell 是 Korn Shell
的 一 个 子 集 , 且 Korn Shell 的 大 多 数 高 级 特 性 都 可 以 在 BASH Shell 中 找 到 。
命 令 和 文 件 名 扩 展 特 性
BASH Shell 命 令 行 有 一 个 与 TCSH Shell 非 常 相 似 的 内 在 特 性 : 命 令 与 文件 名 扩 展 特 性 。 当 你 输 入 一 个 还 没 完 成 的 命 令 或 文 件 名 时 , 你 只 需 键 入 TAB 键 就 能 激 活 命 令 与 文 件 名 扩 展 特 性 , 帮 你 完 成 该 命 令 剩 余 的 输 入 。 如 果 有 多 个命 令 或 文 件 的 前 缀 相 同 , BASH Shell 将 响
铃 并 等 待 你 输 入 足 够 的 字 符 , 以 便 选 择 唯 一 的 命 令 或 文 件 名 。 在 下 面 的 例子 中 , 用 户 键 入 cat 命 令 和 一 个 还 没 有 输 全 的 文 件 名 , 通 过 键 入 TAB 键 , 系 统开 始 搜 索 与 之 匹 配 的 命 令 或 文 件 名 , 如 果 找 到 , 系 统 将 自 动 输 入 搜 索 到 的 命 令或 文 件 名 。 用 户 敲 ENTER 键 后 , 系 统 将 执 行 这 条 命 令 。
$ cat pre TAB
$ cat preface
BASH Shell 也 能 列 出 你 当 前 目 录 下 的 部 分 匹 配 的 文 件 名 来 完 成 文 件 名 扩展 。 如 果 你 键 入 “ ESC ” 键 , 然 后 键 入 “ ? ” , Shell 将 列 出 所 有 与 你 输 入 的 字符 串 相 匹 配 的 文 件 名 。我 们 看 下 面 的 例 子 :在 没 有 完 成 的 输 入 后 键 入“ ESC ? ”, Shell 将 列 出 所 有 与 输 入 的 字 符 串 相 匹 配 的 文 件 名 , 然 后 Shell 回 显 命 令 行 , 根据 列 出 的 文 件 名 , 你 可 以 键 入 你 要 输 入 的 文 件 名 或 按 “ TAB ” 键 来 完 成 文 件 名的 字 符 扩 展 。
$ ls
document docudrama
$cat doc ESC ? document docudrama
$ cat docudrama
命 令 行 编 辑
BASH Shell 本 身 具 有 命 令 行 编 辑 功 能 , 能 使 你 在 执 行 所 键 入 的 命 令 之 前 方便 地 修 改 你 所 键 入 的 命 令 。 如 果 你 在 键 入 命 令 时 犯 了 一 个 拼 写 错 误 , 你 只 需 在运 行 你 所 键 入 的 命 令 之 前 , 使 用 编 辑 命 令 来 纠 正 你 的 拼 写 错 误 , 然 后 执 行 它 , 而 不 用 再 重 新 输 入 整 行 命 令 。 这 对 那 些 要 键 入 长 路 径 文 件 名 作 参 数 的 命 令 特 别有 用 。
命 令 行 编 辑 的 操 作 是 Emacs 编 辑 命 令 的 子 集 。 你 可 用 CTRL-f 或 者 右 方 向键 向 前 移 向 一 字 符 , CTRL-b 或 者 左 方 向 键 向 后 移 向 一 字 符 。 CTRL-d 或 DEL 键 将 删 除 光 标 所 在 位 置 的 字 符 。 要 增 加 字 符 , 只 需 把 光 标 移 到 你 所 希 望 插 入 字符 的 地 方 , 插 入 新 的 字 符 。 在 任 何 时 候 你 可 以 键 入 “ ENTER ” 键 去 执 行 一 个 命令 。 在 下 一 节 , 你 将 用 命 令 行 编 辑 操 作 去 修 改 你 先 前 所 键 入 的 命 令 。
实 用 命 令
在 BASH Shell 中, history 实 用 命 令 能 够 保 存 你 最 近 所 执 行 的 一 些 命 令 。这 些 最 近 你 所 执 行 的 命 令 在 被 history 实 用 命 令 保 存 时 ,其 历 史 记 录 号 从 1 开 始 , 但 只 有 有 限 个 命 令 可 以 被 保 存 下 来 , 其 缺 省 值 是 500 。 history 实 用 命 令 用 一 小段 内 存 来 记 录 有 限 个 最 近 你 所 执 行 的 命 令 。 要 查 看 最 近 你 所 执 行 的 一 组 命 令 , 只 用 键 入 history 命 令 , 然 后 键 入 ENTER ( 回 车 键 ) , 你 最 近 所 执 行 的 一 组 命令 即 按 执 行 的 先 后 顺 序 被 显 示 出 来 ( 命 令 前 的 数 字 为 历 史 记 录 号 ) 。
$ history
1 cp mydata today 2 vi m ydata
-
mv mydata reports
-
cd reports 5 ls
...
所 有 这 些 命 令 都 被 称 之 为 事 件 ( even t) 。 一 个 事 件 表 示 一 个 操 作 已 经 发 生 , 也 即 一 个 命 令 被 执 行 。 这 些 事 件 根 据 它 们 被 执 行 的 先 后 顺 序 用 数 字 给 以 标 识 , 这 一 标 识 称 为 历 史 事 件 号 。 最 后 执 行 的 历 史 事 件 的 事 件 号 最 大 。 每 个 事 件 都 可被 它 的 历 史 事 件 号 或 命 令 的 初 始 字 符 或 字 符 串 等 确 定 。
histroy 实 用 命 令 能 够 使 你 查 询 以 前 的 事 件 , 并 可 把 它 们 显 示 到 命 令 行 上 或执 行 它 。 最 简 便 的 办 法 是 通 过 上 下 光 标 键 , 把 先 前 的 一 个 个 事 件 逐 次 显 示 到 命令 行 。 你 不 必 要 先 运 行 history 命 令 , 就 可 执 行 上 述 操 作 。 按 一 下 上 光 标 键 , 你
上 一 次 执 行 的 一 个 事 件 将 出 现 在 命 令 行 上 , 再 按 一 下 , 上 一 次 的 前 一 事 件 又 会出 现 在 命 令 行 上 ; 按 一 下 下 光 标 键 , 将 会 使 当 前 事 件 的 下 一 事 件 出 现 在 光 标 行上 。 BASH Shell 也 可 以 通 过 键 入 “ ESC ” 、 “ TAB ” 键 来 完 成 对 历 史 事 件 的 字符 扩 展 。 正 如 标 准 的 命 令 行 扩 展 特 性 , 你 键 入 历 史 事 件 的 部 分 字 符 串 , 然 后 键入 “ ESC ” , 再 键 入 “ TAB ” 键 , 与 你 刚 才 键 入 的 字 符 串 相 匹 配 的 历 史 事 件 将自 动 扩 展 并 回 显 到 命 令 行 处 。 如 果 不 止 一 个 事 件 与 你 输 入 的 字 符 串 相 匹 配 , 你将 会 听 到 一 声 响 铃 , 继 续 键 入 字 符 或 字 符 串 , Shell 将 会 唯 一 确 定 你 所 要 键 入 的历 史 事 件 。 然 后 , 你 可 以 用 命 令 行 编 辑 操 作 来 编 辑 显 示 在 命 令 行 上 的 事 件 。 通过 左 右 键 在 命 令 行 上 移 动 , 你 可 以 把 光 标 停 留 在 任 何 地 方 , 插 入 你 所 需 要 的 字符 或 字 符 串 , 如 用 BACKSPACE 键 和 DEL 键 , 你 可 以 删 除 字 符 或 字 符 串 。 按回 键 后 , 这 一 事 件 将 被 执 行 。 你 也 可 以 通 过 ! 命 令 来 查 询 和 执 行 历 史 事 件 。 在 ! 命 令 最 后 键 入 能 够 确 定 历 史 事 件 的 关 联 字 符 , 这 关 联 字 符 可 以 是 历 史 事 件 的 历史 事 件 号 , 或 者 该 事 件 的 前 几 个 字 符 串 。 在 下 面 的 例 子 中 , 历 史 事 件 号 为 3 的事 件 被 查 询 到 。 同 时 , 又 用 其 开 头 几 个 字 符 串 去 匹 配 , 也 被 查 询 到 。
$ !3
mv mydata reports
$ !mv
mv mydata reports
你 也 可 以 用 一 个 偏 移 量 ( 相 对 于 历 史 事 件 列 表 中 最 后 一 个 事 件 ) 来 查 询 历史 事 件 。 负 的 偏 移 量 将 通 从 历 史 事 件 列 表 表 尾 向 前 偏 移 , 从 而 查 询 到 所 要 的 事件 。 在 下 面 的 例 子 中 , 历 史 事 件 号 为 2 的 事 件 “ vi mydata ” 就 是 用 一 个 负 的 偏移 量 查 询 到 , 并 执 行 的 。 必 须 注 意 的 是 , 这 个 偏 移 量 是 相 对 于 相 对 于 历 史 事 件列 表 中 的 最 后 一 个 事 件 的 。 在 本 例 中 , 历 史 事 件 列 表 中 最 后 一 个 事 件 是 事 件 5 ,
历 史 事 件 列 表 中 第 一 个 事 件 为 1 。 从 历 史 事 件 号 为 5 的 事 件 , 往 前 偏 移 4 , 即是 历 史 事 件 号 为 2 的 事 件 。
$ ! -4
vi m ydata
如 果 “ !” 命 令 后 没 有 任 何 参 数 , 则 系 统 将 默 认 为 上 一 事 件 。 在 下 面 的 例 子中 , 用 户 在 命 令 行 上 键 入 无 参 数 的 “ !” 命 令 , 系 统 将 执 行 上 一 事 件 。 本 例 中 , 上 一 事 件 为 “ ls ” 命 令 。
$ !ls
mydata today reports
你 也 可 以 用 模 式 去 搜 索 一 个 历 史 事 件 。 该 搜 索 的 模 式 必 须 用 符 号 “ ? ” 括 起来 。 在 下 面 的 例 子 中 , 模 式 “ ?myd? ” 用 来 搜 索 历 史 事 件 号 为 3 的 历 史 事 件 vi mydata 。
$ !? m yd? vi m ydata
历 史 事 件 编 辑
你 也 可 以 编 辑 历 史 事 件 列 表 中 你 先 前 执 行 的 任 何 事 件 。 在 BASH Shell 中 , 有 两 种 方 法 来 实 现 。 你 可 以 用 命 令 行 编 辑 功 能 去 查 询 和 编 辑 历 史 事 件 列 表 中 的任 何 事 件 。 同 时 , 你 也 可 以 用 history fc 命 令 选 项 来 查 询 一 个 事 件 并 用 全 屏 幕 编辑 器 vi 来 编 辑 它 。 两 种 方 法 涉 及 到 两 种 不 同 的 编 辑 器 。 前 一 种 命 令 的 局 限 性 在于 它 只 能 用 命 令 行 行 编 辑 器 进 行 单 行 编 辑 ( 其 编 辑 命 令 是 Emacs 编 辑 器 命 令 的子 集 ) 。 但 是 , 它 能 使 你 非 常 方 便 地 查 询 历 史 事 件 列 表 中 的 事 件 。 第 二 种 方 法
用 功 能 强 大 的 标 准 全 屏 幕 编 辑 器 vi 来 完 成 编 辑 , 但 它 仅 针 对 某 些 特 定 的 历 史 事件 。
用 命 令 行 编 辑 器 , 你 不 仅 可 以 编 辑 当 前 的 命 令 , 而 且 可 以 编 辑 历 史 事 件 列表 中 的 事 件 并 执 行 之 。 你 可 以 用 CTRL-P 命 令 转 移 到 历 史 事 件 列 表 中 当 前 的 事件 的 前 一 事 件 , 用 CTRL-n 命 令 转 移 到 历 史 事 件 列 表 中 当 前 的 事 件 的 下 一 事 件 , 用 E S C <命 令 转 移 到 历 史 事 件 列 表 中 最 初 的 一 事 件 , 用 ESC > 命 令 转 移 到 历 史事 件 列 表 中 的 最 后 一 事 件 。 你 甚 至 可 以 用 一 种 方 式 去 搜 索 指 定 的 事 件 , 例 如 , 在 反 斜 “ \ ” 后 键 入 搜 索 模 式 将 在 历 史 文 件 列 表 中 向 后 (backward) 搜 索 历 史 文件 , 而 在 问 号 “ ? ” 后 键 入 搜 索 模 式 将 向 前 (forward) 搜 索 历 史 文 件 。 键 入 “ n ” 命 令 重 复 进 行 上 次 搜 索 。
一 旦 你 找 到 编 辑 的 事 件 , 你 可 以 使 用 Emacs 命 令 行 编 辑 命 令 对 该 文 件 进 行行 编 辑 。按 CTRL-d 进 行 字 符 删 除 ,CTRL-f 或 光 标 右 键 前 移 一 个 字 符 串 ,CRTL-b 或 光 标 左 键 后 移 一 个 字 符 。 如 果 要 增 加 一 个 字 符 , 把 光 标 移 到 你 需 要 输 入 字 符的 地 方 键 入 字 符 即 可 。 表 15-1 列 出 了 查 询 历 史 事 件 列 表 的 各 种 命 令 。
如 果 想 用 标 准 的 编 辑 器 对 一 事 件 进 行 编 辑 , 你 可 以 用 fc 命 令 及 一 个 指 定 的事 件 关 联 ( 如 历 史 事 件 号 ) 来 查 询 该 事 件 , 此 时 , 系 统 所 使 用 的 编 辑 器 是 Shell 为 fc 命 令 指 定 的 缺 省 编 辑 器 。 下 面 的 例 子 将 用 标 准 编 辑 器 编 辑 历 史 事 件 号 为 4 的 事 件 cd reports , 然 后 执 行 之 。
$ fc 4
你 可 以 也 可 以 一 次 选 择 多 个 命 令 进 行 编 辑 并 执 行 。 通 过 先 输 入 第 一 个 命 令的 标 识 符 , 然 后 输 入 最 后 一 个 命 令 的 标 符 来 选 择 多 个 命 令 。 这 一 标 识 符 可 以 是命 令 的 历 史 事 件 号 , 也 可 以 是 命 令 的 初 始 字 符 或 字 符 串 。 在 下 面 的 例 子 中 , 用
历 史 事 件 号 来 选 择 在 事 件 号 在 2 与 4 之 间 的 一 系 列 命 令 , 然 后 编 辑 并 运 行 它 们 。另 一 例 子 采 用 历 史 事 件 列 表 中 初 始 字 符 或 字 符 串 来 作 标 识 符 。
$ fc 2 4
$ fc vi c
fc 使 用 缺 省 的 编 辑 器 , 这 一 缺 省 编 辑 器 被 FCEDIT 某 些 特 殊 变 量 所 指 定 。通 常 这 一 编 辑 器 为 vi 编 辑 器 。 但 是 , 如 果 你 想 使 用 Emacs 编 辑 器 , 在 你 使 用fc 命 令 时 , 你 可 以 用 -e 选 项 和 emacs 选 项 。 下 面 的 例 子 将 用 Emacs 编 辑 器 对事 件 号 为 4 的 事 件 cd reports 进 行 编 辑 , 然 后 运 行 。
$ fc -e emacs 4
配 置 H istory: HISTFILE 及 HISTSIZE
你 系 统 所 保 存 的 事 件 数 被 保 存 在 一 个 特 定 的 系 统 变 量 中 , 这 个 变 量 就 是H ISTSIZE 。 这 个 变 量 的 缺 省 值 通 常 被 设 置 为 500 。 你 可 以 非 常 简 单 方 便 地 改 变它 的 值 , 并 赋 之 以 新 的 值 。 在 下 面 的 例 子 中 , 用 户 重 新 设 置 变 量 HISTSIZE 的值 为 10 。
$ HISTSIZE=10
实 际 上 , 历 史 事 件 被 保 存 在 一 个 文 件 中 , 而 这 个 文 件 名 由 变 量 H ISTFILE 指 定 。 通 常 这 个 文 件 的 缺 省 名 是 .bash_history 。 但 是 , 你 可 以 通 过 给 变 量H ISTFILE 赋 值 ,来 指 定 新 的 文 件 名 。在 下 面 的 例 子 中 ,显 示 出 了 变 量 HISTFILE 的 值 ,然 后 ,新 的 文 件 名 newhist 被 赋 值 给 它 ,所 有 历 史 事 件 将 被 保 存 在 newhist 文 件 中 。
$ echo $HISTFILE
.bash_history
$ HISTFILE= “ newhis t”
$ echo $HISTFILE newhist
别 名
通 过 alias 命 令 , 你 可 以 给 一 个 命 令 创 建 一 个 新 的 名 字 。 alias 命 令 象 一 个宏 , 对 其 代 表 的 命 令 进 行 替 换 。 它 不 是 逐 字 对 命 令 名 进 行 替 换 , 而 是 仅 仅 对 命令 取 另 外 一 个 名 字 。
alias 命 令 由 关 键 词 alias 开 头 , 然 后 是 要 替 换 命 令 的 新 的 名 字 , 其 后 是 等号 ( = ) 及 将 要 替 换 的 命 令 , 在 等 号 之 间 不 能 有 空 格 。 下 面 的 例 子 中 , list 就 是 ls 命 令 的 一 个 别 名 。
$ alias list=ls
$ ls
mydata today
$ list
mydata today
$
你 也 可 以 用 一 个 别 名 对 一 个 命 令 或 其 选 项 进 行 替 换 。 但 是 , 你 必 须 用 一 对单 引 号 把 它 们 括 起 来 。 所 有 包 括 空 格 的 别 名 必 须 用 单 引 号 把 它 们 括 起 来 。 在 下面 的 例 子 中 , lss 是 带 -s 选 项 ls 命 令 的 别 名 , lsa 是 带 -F 选 项 的 ls 命 令 的 别 名 。带 -s 选 项 的 ls 命 令 将 列 出 文 件 及 它 们 的 文 件 占 的 块 大 小 ; 带 -F 选 项 的 ls 命 令
将 在 目 录 名 前 加 一 “ /” 。 需 要 主 要 的 是 , 对 命 令 和 其 选 项 要 单 引 号 把 它 们 括 起来 。
$ alias lss='ls -l'
$ lss
mydata 14 today 6 reports 1
$ alias lsa='ls -F'
$ lsa
mydata today /reports
$
你 也 许 经 常 对 一 个 带 参 数 选 项 的 命 令 取 别 名 。 如 果 你 经 常 执 行 带 有 复 杂 参数 组 合 的 命 令 , 你 可 能 想 用 简 单 的 别 名 来 代 替 。 例 如 : 假 如 你 常 常 想 列 出 所 有你 的 源 程 序 和 目 标 代 码 文 件 , 假 设 这 些 文 件 分 别 以 .c 和 .o 为 扩 展 名 , 那 么 你 需要 用 带 参 数 的 ls 命 令 ( 此 时 这 个 参 数 是 特 定 的 字 符 串 *.[ co ] ) , 于 是 , 你 可以 用 别 名 给 这 个 命 令 取 别 名 。 下 面 给 出 的 例 子 中 , 用 ls
c 给 带 参 数 * .[ co ]的 ls 命 令 取 别 名 。
$ alias lsc='ls * .[ co ] '
$ lsc
main.c main.o lib.c lib.o
你 也 可 以 用 一 个 Shell 命 令 名 给 一 个 命 令 行 取 别 名 。 这 在 你 要 执 行 带 特 定 选项 的 Shell 命 令 时 非 常 有 用 。 例 如 带 -i 选 项 的 rm 、 cp 及 m v 命 令 通 常 用 来 保 证不 覆 盖 已 存 在 的 同 名 的 文 件 。 如 果 你 在 使 用 上 述 命 令 的 过 程 中 , 希 望 系 统 给 予相 应 的 提 示 来 确 认 你 是 否 想 覆 盖 已 有 的 文 件 , 你 可 以 给 它 们 取 别 名 去 包 含 这 一选 项 。 例 如 : 下 面 的 命 令 就 是 用 带 -i 选 项 的 rm 、 cp 及 m v 命 令 取 别 名 为 rm 、 cp
及 m v 的 。
$ alias rm=' rm -i'
$ alias mv=' mv -i'
$ alias cp=' cp -i'
不 带 任 何 参 数 的 alias 命 令 将 列 出 所 有 当 前 已 经 起 作 用 的 别 名 及 它 们 所 代 表的 命 令 。 你 可 以 用 unalias 命 令 去 删 除 一 个 别 名 。 在 下 面 的 例 子 中 , 用 户 列 出了 当 前 所 有 的 别 名 , 然 后 用 unalias 命 令 删 除 别 名 lsa 。
$ alias lsa=ls -F list=ls rm=rm -i
$ unalias lsa
控 制 Shell 的 运 行 方 式
BASH Shell 有 一 些 特 殊 变 量 , 能 让 你 控 制 Shell 以 不 同 的 方 式 工 作 。 例 如 : 变 量 noclobber 能 防 止 在 重 定 向 输 出 时 意 外 地 覆 盖 一 个 文 件 。 你 可 以 通 过 set 命 令 来 使 noclobber 特 殊 变 量 有 效 或 无 效 。 set 命 令 有 两 个 参 数 : 一 个 选 项 来 指定 变 量 开 ( on ) 或 关 ( off) , 另 一 变 量 是 特 殊 变 量 的 变 量 名 。 要 使 一 特 殊 变 量开 ( 有 效 ) , 用 -o 选 项 , 要 使 其 关 ( 无 效 ) , 用 +o 选 项 。
例 如 :
$ set -o feature// 使 feature 变 量 开
$ set +o feature // 使 feature 变 量 关
三 个 最 常 用 的 Shell 特 殊 变 量 变 量 有 : ignoreeo f、 noclobber 及 noglob。 表
- 列 出 了 set 命 令 的 用 法 及 几 个 Shell 特 殊 变 量 的 作 用 。
15.5.1ignoreeof
设 置 了 ignoreeof 变 量 后 , 你 将 不 能 使 用 CTRL-d 来 退 出 Shell 。 CTRL-d 不 仅 被 用 来 退 出 Shell, 而 且 可 以 用 来 终 止 用 户 直 接 输 往 标 准 输 出 上 的 输 入 。 该操 作 经 常 在 MailX 程 序 和 一 些 Shell 实 用 命 令 中 使 用 , 例 如 cat 实 用 命 令 。 你 可能 在 上 述 实 用 程 序 操 作 中 , 非 常 容 易 误 操 作 而 意 外 地 退 出 Shell 。 ignoreeof 特殊 变 量 正 是 用 来 防 止 这 些 意 外 的 退 出 。 在 下 面 的 例 子 中 , 用 带 -o 选 项 的 set 命令 来 使 ignoreeof 特 殊 变 量 有 效 (on), 这 时 , 用 户 只 能 用 logout 或 exit 命 令 退出 Shell 。
$ set -o ignoreeof
$ ctrl-d
Use exit to logout
$
15.5.2noclobber
设 置 了 noclobber 变 量 后 , 可 以 使 在 重 定 向 输 出 时 保 护 已 存 在 的 文 件 。 如果 你 用 重 定 向 把 输 出 保 存 到 一 个 已 经 存 在 的 文 件 中 时 , noclobber 这 一 特 殊 变量 可 以 防 止 文 件 在 进 行 标 准 输 出 时 被 意 外 覆 盖 , 原 文 件 将 被 受 到 保 护 。 这 种 情况 有 可 能 发 生 在 把 重 定 向 输 出 的 内 容 保 存 到 你 输 入 的 文 件 名 中 , 而 你 给 出 的 这
个 文 件 名 可 能 已 经 存 在 了 。 因 此 , noclobber 特 殊 变 量 可 以 防 止 你 意 外 地 覆 盖一 个 你 已 经 存 在 的 原 文 件 。 下 面 的 例 子 中 , 用 户 设 置 noclobber 特 殊 变 量 为 有效 ( on ) , 在 重 定 向 时 , 用 户 试 图 去 覆 盖 系 统 已 经 存 在 的 文 件 myfile , 此 时 , 系 统 将 返 回 一 错 误 信 息 。
$ set -o noclobber
$ cat preface>myfile myfile: file exists
$
你 可 能 觉 得 你 的 确 是 想 在 重 定 向 输 出 时 覆 盖 这 个 文 件 , 系 统 的 这 一 提 示 将浪 费 你 的 时 间 , 这 时 , 你 可 以 在 重 定 向 操 作 算 子 后 面 加 一 惊 叹 号 ( !) 。 于 是 , 系 统 将 不 考 虑 noclobber 变 量 的 有 效 性 而 直 接 把 重 定 向 输 出 的 内 容 输 出 至 指 定的 文 件 。
$ cat preface >! myfile
15.5.3noglob
设 置 了 noglob 变 量 后 , Shell 将 不 扩 展 文 件 名 中 一 些 特 殊 的 字 符 或 字 符 串 。例 如 : 字 符 “ * ” 、 “ ? ” 、 “ [ ” 、 “ ] ” 及 “ ~ ” 等 字 符 将 不 再 展 开 多 义 性 文件 名 与 一 文 件 名 相 匹 配 。 如 果 你 在 文 件 名 中 使 用 了 这 些 特 殊 字 符 , 这 个 特 殊 变量 或 许 就 对 你 有 用 。 下 面 的 例 子 中 , 如 果 用 户 希 望 列 出 结 尾 为 “ ? ” 的 文 件 名answer? , 可 通 过 如 下 步 骤 : 首 先 , 用 户 使 noglob 变 量 为 无 效 ( 关 ) , 然 后 再列 出 文 件 名 。 可 以 看 到 , 目 前 命 令 行 上 的 问 号 ( “ ? ” ) 被 认 为 是 文 件 名 中 的 一个 字 符 , 而 不 是 被 看 作 一 个 特 殊 的 字 符 ( 代 表 任 意 一 字 符 ) 。
$ set -o noglob
$ ls answer? answer?
环 境 变 量 与 子 Shell : export 命 令
当 你 登 陆 到 你 的 帐 号 后 , Linux 系 统 将 创 建 你 的 用 户 Shell 。 在 此 shell 中 , 你 可 以 使 用 Shell 命 令 或 申 明 变 量 。你 也 可 以 创 建 并 运 行 Shell 脚 本 程 序 。然 而 , 当 你 运 行 一 个 Shell 脚 本 程 序 时 , 系 统 将 创 建 一 个 子 Shell 。 此 时 , 系 统 中 将 有两 个 Shell , 一 个 是 你 登 陆 时 系 统 的 缺 省 Shell , 另 一 个 是 系 统 为 运 行 脚 本 程 序创 建 的 Shell。在脚本程序 Shell 中 , 你 可 以 执 行 有 自 己 Shell 的 另 一 脚 本 Shell 。当 一 个 脚 本 程 序 运 行 完 毕 , 它 的 脚 本 Shell 将 终 止 , 你 可 以 返 回 到 你 执 行 该 脚本 之 前 的 Shell 。 从 这 种 意 义 上 来 说 , 你 可 以 有 许 多 Shell , 每 个 Shell 都 “ 寄生 ” 在 某 Shell 之上 ( 称 之 为 父 Shell ) 。
在 一 个 子 Shell 内 定 义 的 变 量 只 在 该 子 Shell 内 有 效 。 如 果 你 在 一 Shell 脚本 程 序 中 定 义 了 一 变 量 , 当 该 脚 本 程 序 运 行 时 , 你 定 义 的 变 量 只 是 该 脚 本 Shell 内 的 一 局 部 变 量 。 其 它 的 Shell 不 能 引 用 它 。 从 这 种 意 义 上 来 说 , 变 量 是 隐 藏在 它 的 Shell 之 内 的 。
你 可 以 在 如 下 三 种 主 要 的 Shell 中 定 义 环 境 变 量 , 即 BASH Shell 、 PDKSH Shell 及 TCSH Shell 。 但 是 , BASH Shell 中 实 现 环 境 变 量 的 机 制 与 TCSH Shel 有 很 大 的 不 同 。 在 BASH Shell 中 , 环 境 变 量 被 输 出 的 。 也 就 是 说 。 环 境 变 量在 每 个 子 Shell 中 都 有 一 个 拷 贝 。 例 如 , 如 果 myfile 这 个 变 量 被 输 出 , 那 么 这个 变 量 在 每 个 子 Shell 中 都 会 为 你 自 动 定 义 。 而 在 TCSH Shell 中 , 环 境 变 量 只
被 定 义 一 次 , 一 旦 被 定 义 , 在 任 何 子 Shell 中 都 可 以 直 接 引 用 。
在 BASH Shell 中 , 一 个 环 境 变 量 可 以 被 认 为 是 一 个 Added capabilities 的常 规 变 量 。 要 使 其 变 量 值 可 以 改 变 , 你 可 以 使 用 export 命 令 对 已 定 义 的 变 量 进行 变 量 输 出 。 export 命 令 将 使 系 统 在 创 建 每 一 个 新 的 Shell 时 定 义 那 个 变 量 的一 个 拷 贝 。 每 个 新 的 Shell 将 有 其 自 己 的 环 境 变 量 的 拷 贝 。 这 个 过 程 常 称 之 为变 量 输 出 。
在 下 面 的 例 子 中 ,变 量 myfile 是 在 dispfile 脚 本 程 序 中 定 义 的 。然 后 用 export 命 令 使 其 成 为 一 环 境 变 量 。 变 量 myfile 将 可 以 输 出 至 任 何 子 Shell , 例 如 当 执 行printfile 脚 本 程 序 时 产 生 的 子 Shell 。
dispfile 脚 本 程 序 清 单 :
/************** begin dispfile ***********/ myfile="List"
export myfile
echo "Displaying $myfile" pr -t -n $myfile
printfile
/************** end dispfile ***********/ printfile 脚 本 程 序 清 单 :
/************** begin printfile ***********/
echo "Printing $myfile" lpr $myfile&
/************** end printfile ***********/
$ dispfile
D isplaying List
-
screen
-
modem
-
paper Printing List
$
把 环 境 变 量 的 输 出 理 解 为 全 局 变 量 是 一 种 误 解 。 一 个 新 的 Shell 绝 不 会 改 变其 Shell 以 外 的 变 量 的 值 。 但 是 , 这 个 变 量 的 值 将 被 传 递 给 这 个 新 创 建 的 Shell 。你 可 以 将 输 出 变 量 理 解 为 将 变 量 的 值 输 出 到 一 个 Shell, 而 不 是 将 它 们 本 身 。 对那 些 比 较 熟 悉 结 构 化 编 程 的 读 者 来 说 , 可 以 把 输 出 变 量 理 解 为 “ 值 引 用 ” 。
用 特 殊 Shell 变 量 设 置 登 陆 Shell
前 面 已 经 指 出 , 在 你 登 陆 进 入 你 的 帐 号 , Linux 系 统 将 为 你 创 建 Shell 。 这个 Shell 被 称 为 你 的 登 陆 Shell 或 用 户 Shell 。 当 你 执 行 Shell 程 序 脚 本 时 , 系统 将 创 建 用 户 Shell 的子 Shell 。 你 可 以 在 你 的 用 户 Shell 下 定 义 变 量 , 你 也 可以 定 义 环 境 变 量 , 而 这 些 环 境 变 量 可 以 被 在 运 行 Shell 程 序 脚 本 时 创 建 的 任 何子 Shell 所 引 用 。
Linux 有 一 些 特 殊 Shell 变 量 , 这 些 变 量 允 许 你 配 置 你 的 用 户 Shell 。 很 多 这
些 特 殊 Shell 变 量 在 你 登 陆 时 系 统 已 经 为 你 定 义 好 , 但 是 , 有 些 变 量 你 可 以 自己 再 定 义 。
这 些 特 殊 变 量 名 是 系 统 的 一 些 保 留 关 键 字 。 你 不 能 用 这 些 关 键 字 作 为 你 自己 的 变 量 名 。 为 使 这 些 特 殊 变 量 容 易 识 别 , 这 些 特 殊 Shell 变 量 都 是 由 一 些 大写 字 母 组 成 的 字 符 串 。 例 如 : 关 键 字 HOME 是 系 统 用 来 定 义 名 为 HOME 的 特殊 变 量 的 , 它 是 一 个 特 殊 环 境 变 量 , 用 来 保 存 用 户 的 主 目 录 路 径 名 。 另 一 方 面 , 前 面 的 章 节 中 介 绍 的 关 键 字 noclobber 用 来 定 义 noclobber 环 境 变 量 , 这 个 特殊 变 量 可 以 防 止 在 重 定 向 输 出 覆 盖 已 有 的 文 件 。
许 多 特 殊 变 量 在 你 登 陆 你 的 用 户 时 被 系 统 自 动 赋 了 初 始 值 , 但 是 , 如 果 需
要 , 用 户 可 以 改 变 这 些 特 殊 变 量 的 值 。 但 是 , 有 些 特 殊 变 量 的 值 是 不 能 被 重 新赋 值 的 。 例 如 , 保 存 用 户 主 目 录 路 径 名 的 特 殊 环 境 变 量 HOME 是 用 户 不 能 给 重新 赋 值 的 。 一 些 命 令 , 例 如 cd 命 令 就 是 通 过 保 存 用 户 主 目 录 的 特 殊 变 量 HOME 来 进 行 目 录 定 位 的 。 一 些 常 用 的 特 殊 环 境 变 量 将 在 本 节 中 详 细 介 绍 。
另 外 一 些 系 统 定 义 并 赋 以 一 定 的 初 始 值 的 特 殊 变 量 是 用 户 可 以 任 意 改 变的 。 你 可 以 重 新 给 它 们 定 义 一 个 新 的 值 。 例 如 , 变 量 PATH 是 系 统 定 义 的 , 在登 陆 时 被 赋 以 一 初 始 值 , 这 一 初 始 值 包 括 了 一 些 命 令 所 在 的 目 录 路 径 。 当 你 执行 某 个 命 令 时 , Shell 将 自 动 搜 索 这 些 路 径 。 你 可 以 在 PATH 变 量 中 增 加 新 的路 径 , 在 执 行 命 令 时 将 对 这 些 新 的 路 径 进 行 搜 索
还 有 一 些 特 殊 变 量 , 用 户 登 陆 系 统 后 并 不 给 它 们 赋 值 。 这 些 变 量 通 常 是 一些 可 选 择 项 。 例 如 , 变 量 EXINIT 允 许 你 为 vi 编 辑 器 进 行 设 置 选 项 。 在 每 次 登陆 系 统 后 , 你 必 须 重 新 为 这 些 变 量 定 义 值 。 从 这 种 意 义 上 说 , 这 些 变 量 可 称 之为 “ 用 户 级 定 义 ” ( user-defined ) 特 殊 变 量 。
这 三 类 特 殊 变 量 没 有 严 格 、 权 威 的 分 类 与 定 义 。 本 书 根 据 它 们 特 点 , 分 别称 这 类 特 殊 变 量 为 : 用 户 不 能 改 变 其 值 的“ 系 统 自 赋 值 ” ( system-determined ) 特 殊 变 量 、 用 户 可 以 重 新 定 义 一 新 值 的 “ 可 重 定 义 ” ( redefinable ) 变 量 及 用户 必 须 自 己 赋 值 的 “ 用 户 级 定 义 ” ( user-defined) 特 殊 变 量 。
你 可 以 用 env 命 令 列 出 当 前 定 义 的 特 殊 变 量 及 其 值 。 env 命 令 与 set 命 令 很相 似 , 但 env 命 令 仅 列 出 系 统 特 殊 变 量 。
$ env USERNAME=chris
ENV=/home/chris/.bashrc H ISTSIZE=1000
H ISTFILE=/home/chris/.bash_history H ISTFILESIZE=1000
HOSTNAME=garnet LOGNAME=chris
H ISTFILESIZE=1000
CDPATH=:$HOME/letters:$HOME/oldletters MAIL=/var/spool/mail/chris
WWW_HOME=fi le:/usr/doc/calderadoc-0.80-1/Caldera_Info TERM= linux
HOSTTYPE=i386
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/home/chris/bin: HOME=/home/chris
SHELL=/bin/bash
PS1= [\ u@ \ h \ w ] \ $
PS2=> MAILCHECK=10000
MAILPATH=/home/mail/chris:/home/chris/projmsgs CRPATH=/usr/lib/CRISPlite/macros OSTYPE=Linux NNTPSERVER=nntp.ix.netcom.com
EXINIT='set nu ai' TZ=PST5PDT SHLVL=1
_=/usr/bin/env
你 可 以 用 称 为 初 始 化 文 件 的 特 殊 脚 本 语 言 去 对 “ 可 重 定 义 ” ( redefinable ) 变 量 及 “ 用 户 级 定 义 ” ( user-defined) 变 量 进 行 自 动 定 义 。 初 始 化 文 件 是 一 个特 殊 的 Shell 脚 本 程 序 , 只 要 用 户 进 入 这 个 特 定 的 Shell , 它 将 自 动 运 行 。 你 可以 对 这 个 初 始 化 文 件 进 行 编 辑 , 给 一 些 特 殊 变 量 进 行 定 义 与 赋 值 。 当 你 进 入Shell , 初 始 化 文 件 将 被 执 行 , 并 对 一 些 特 殊 变 量 进 行 定 义 与 赋 值 , 从 而 有 效 地给 这 些 特 殊 变 量 赋 予 你 所 定 义 的 值 。 例 如 , 在 BASH Shell 中 , 其 初 始 化 文 件是 .profile , 当 你 每 次 登 陆 进 入 Linux 时 , 该 文 件 都 被 自 动 运 行 。 该 文 件 包 含 了一 些 特 殊 变 量 的 定 义 与 赋 值 。 因 为 .profile 文 件 仅 仅 是 一 种 Shell 脚 本 程 序 , 因此 , 你 可 以 用 任 何 一 种 编 辑 器 对 其 进 行 编 辑 , 例 如 vi 编 辑 器 。 如 果 需 要 , 你 可以 改 变 那 些 特 殊 变 量 的 值 。
在 BASH Shell 中 , 所 有 “ 可 重 定 义 变 量 ” ( redefinable )及 “ 用 户 级 定 义
变 量 ” ( user-defined) 是 为 环 境 变 量 而 设 置 的 。 当 你 定 义 或 重 定 义 一 特 殊 变 量时 , 你 必 须 对 其 进 行 输 出 ( export ) , 以 使 其 成 为 环 境 变 量 。 这 意 味 着 你 对 任
何 特 殊 变 量 的 改 变 都 必 须 用 export 变 量 进 行 输 出 。 在 登 陆 初 始 化 文 件 .profile 文件 的 结 尾 , 你 会 看 到 通 常 有 一 export 命 令 来 对 该 文 件 中 定 义 的 所 有 特 殊 变 量 进行 输 出 。
“ 系 统 自 赋 值 ” ( system-determined ) 特 殊 变 量
在 这 里 , 将 介 绍 三 个 常 见 的 系 统 “ 系 统 自 赋 值 ” ( system-determined ) 特殊 变 量 , 它 们 是 : HOME 、 LOGNAME 及 TZ 。 当 你 一 登 陆 , 系 统 就 自 动 定 义它 们 , 你 可 以 访 问 它 们 的 值 , 但 不 能 改 变 它 们 。 它 们 都 是 环 境 变 量 , 任 何 的 子Shell 都 可 以 访 问 它 们 的 值 。
HOME
HOME 变 量 保 存 你 主 目 录 的 路 径 名 。 这 个 主 路 径 是 系 统 管 理 员 在 创 建 你 的用 户 时 由 系 统 管 理 员 指 定 的 。 当 你 登 陆 进 入 你 的 帐 号 时 , 系 统 将 自 动 把 主 目 录路 径 名 保 存 到 HOME 变 量 中 。 下 面 的 例 子 中 , 用 echo 命 令 列 出 变 量 HOME 的 值 。
$echo $HOME
/home/chris
当 你 需 要 指 定 绝 对 路 径 时 , 我 们 经 常 用 到 HOME 变 量 。 在 下 面 的 例 子 中 , 用 保 存 了 主 目 录 名 的 HOME 变 量 来 指 定 reports 的 绝 对 路 径 名 。
$ ls $HOME/reports LOGNAME
LOGNAME 变 量 保 存 你 的 登 陆 名 , 而 不 是 路 径 名 。 如 果 用 户 以 用 户 名 chris
登 陆 , 系 统 将 以 字 符 串 “ chris ” 作 为 变 量 LOGNAME 的 值 。 在 某 些 情 况 下 , 你
需 要 使 用 你 的 登 陆 名 , 这 时 , 你 可 以 使 用 LOGNAME 变 量 。 下 面 的 例 子 将 介 绍LOGNAME 变 量 的 使 用 。 我 们 知 道 , 用 户 的 mail 信 箱 的 目 录 名 与 其 登 陆 用 户 名相 同 , 用 户 可 以 直 接 使 用 他 的 登 陆 名 或 简 单 方 便 地 引 用 LOGNAME 变 量 的 值 定位 mail 目 录 。 如 果 有 时 用 户 决 定 要 改 变 其 登 陆 名 , 那 么 , 他 们 更 愿 意 使 用LOGNAME 变 量 。
$ ls /usr/mail/$LOGNAME TZ
TZ 变 量 用 来 指 定 系 统 所 使 用 的 时 区 。 它 是 在 你 登 陆 进 入 系 统 时 由 系 统 设 置的 。 在 TZ 变 量 中 , 用 三 个 字 段 来 显 示 其 值 。 前 三 个 字 母 显 示 当 地 时 区 , 下 一个 字 母 是 当 地 时 区 与 格 尼 威 制 标 准 时 间 ( Greenwich mean tim e) 的 时 差 数 , 最 后 的 三 个 字 母 是 当 地 的 夏 令 时 ( Daylight Saving ) 时 区 。 下 面 的 例 子 中 , TZ 变 量 保 存 的 是 太 平 洋 标 准 时 间 ( Pacific standard tim e) , 它 和 格 尼 威 制 标 准 时间 的 时 差 是 八 个 小 时 , 使 用 的 是 太 平 洋 夏 令 时 。
$ echo $TZ PST8PDT
BASH Shell 可 重 定 义 特 殊 变 量
可 重 定 义 变 量 保 存 如 下 一 些 信 息 : Linux 命 令 所 在 的 路 径 名 、 ma il 信 箱 中 文件 的 路 径 名 以 及 你 的 命 令 提 示 符 等 。 你 可 以 通 过 简 单 的 赋 值 操 作 来 修 改 上 述 任何 变 量 的 值 。 另 外 一 些 常 用 的 可 重 定 义 的 特 殊 变 量 有 : SHELL 、 PATH 、 PS1 、PS 2 、 及 MAIL 等 。 SHELL 变 量 保 存 你 所 登 陆 后 使 用 的 Shell 类 别 ( 包 括 路 径的 程 序 名 ) 。 PATH 变 量 保 存 执 行 Linux 命 令 时 要 搜 索 的 目 录 表 。 PS1 和 PS2
变 量 保 存 命 令 提 示 符 的 值 。 MAIL 变 量 用 来 保 存 你 的 邮 件 信 箱 中 文 件 的 路 径 名 。
SHELL
在 Linux 系 统 中 , 当 你 登 陆 时 , 系 统 将 启 动 BASH Shell 、 PDKSH Shell 及TCSH Shell 这 三 种 Shell 中 的 任 何 一 种 。而 SHELL 变 量 将 保 存 系 统 启 动 的 Shell 名 ( 包 括 目 录 路 径 名 ) , 也 就 是 你 的 缺 省 Shell。 Shell 程 序 放 置 在 /bin 目 录 下 。下 面 是 不 同 Shell 程 序 所 在 的 目 录 路 径 列 表 :
BASH Shell : /bin/bash PDKSH Shell : /bin/pdksh TCSH Shell : /bin/tcsh
在 下 面 的 例 子 显 示 出 SHELL 变 量 的 值 。
$ echo $SHELL
/bin/bash
PATH
PATH 变 量 保 存 一 系 列 由 “ : ” 号 分 开 的 目 录 路 径 。 每 次 要 执 行 一 个 命 令时 , 系 统 将 对 在 PATH 变 量 中 列 出 的 路 径 名 逐 一 进 行 搜 索 , 以 找 到 要 执 行 的 命令 。例 如 , cp 命 令 放 置 在 linux 系 统 中 的 /usr/bin 路 径 下 ,这 个 目 录 路 径 是 PATH 变 量 中 列 出 的 目 录 路 径 之 一 。 在 每 次 执 行 cp 命 令 之 前 , 系 统 将 搜 索 这 一 路 径 , 从 而 找 到 cp 应 用 程 序 。 系 统 会 给 PATH 变 量 定 义 一 初 始 值 。 在 Linux 系 统 中 , PATH 变 量 的 初 始 路 径 名 为 usr/bin 和 /usr/sbin 。
Shell 可 执 行 任 何 可 执 行 文 件 , 包 括 你 开 发 或 创 建 的 应 用 程 序 或 脚 本 程 序 。
因 此 , PATH 变 量 也 可 以 搜 索 你 的 工 作 目 录 。 如 果 你 想 在 你 的 工 作 目 录 下 运 行你 自 己 的 脚 本 程 序 或 应 用 程 序 , Shell 也 可 以 搜 索 到 它 们 。
在 PATH 变 量 保 存 的 字 符 串 中 , 路 径 和 路 径 之 间 不 能 有 空 格 。 如 果 该 字 符串 中 仅 仅 只 有 一 个 “ : ” 号 而 没 有 指 定 特 定 的 路 径 , 那 么 , 系 统 将 仅 搜 索 你 的工 作 目 录 。 在 整 个 字 符 串 的 结 尾 加 一 个 “ : ” 号 表 示 包 括 你 的 工 作 目 录 。 例 如 : 字 符 串 /usr/bin:/usr/sbin :表 示 将 要 搜 索 三 个 目 录 , 即 目 录 /usr/bin 、 /usr/sbin 及你 当 前 的 工 作 目 录 。
$ echo $PATH
/usr/bin:usr/sbin:
如 果 需 要 , 你 可 以 任 意 加 入 新 的 路 径 至 PATH 变 量 中 。 如 果 你 用 Shell 脚本 程 序 创 建 了 几 个 你 自 己 的 Linux 命 令 , 那 么 , 上 述 特 性 就 非 常 实 用 。 你 可 以创 建 一 个 目 录 , 并 把 上 述 新 的 Shell 脚 本 命 令 放 到 这 个 目 录 , 然 后 把 该 目 录 加到 PATH 变 量 中 , 于 是 , 无 论 你 在 何 目 录 下 , 你 都 可 以 执 行 上 述 Shell 脚 本 命令 。 因 为 在 PATH 变 量 中 已 包 含 了 脚 本 命 令 所 在 目 录 字 符 串 , 当 你 发 出 执 行 一个 脚 本 命 令 的 时 候 , 系 统 每 次 都 对 该 目 录 进 行 搜 索 。
你 可 以 用 变 量 赋 值 的 方 式 往 PATH 变 量 的 路 径 列 表 中 增 加 一 个 新 的 路 径 ,
并 且 可 以 在 你 的 Shell 下 直 接 执 行 这 一 赋 值 过 程 。 看 下 面 的 例 子 : 用 户 chris 向PATH 变 量 中 增 加 了 一 新 的 名 为 m ybin 的 路 径 。 尽 管 你 可 以 仔 细 地 往 PATH 变量 中 键 入 所 有 路 径 名 列 表 及 新 的 路 径 名 来 完 成 这 一 赋 值 过 程 , 但 你 可 以 用
$PATH 给 PATH 变 量 赋 值 , 然 后 加 入 新 的 路 径 名 。 下 面 的 例 子 中 , 增 加 的 新的 路 径 名 中 的 HOME 的 值 用 来 代 表 用 户 的 主 目 录 。 必 须 注 意 的 是 在 两 个 “ : ” 号 之 间 没 有 任 何 字 符 串 , 表 示 要 搜 索 工 作 目 录 。
$PATH=$PATH:$HOME/mybin
$export PATH
$echo $PATH
/usr/bin:/usr/sbin::/home/chris/mybin
如 果 你 仅 在 登 陆 后 才 往 PATH 变 量 中 增 加 一 个 目 录 , 那 么 , 这 个 目 录 仅 仅是 在 你 的 登 陆 期 间 被 增 加 。 当 你 退 出 用 户 , 然 后 重 新 登 陆 , 登 陆 初 始 化 文件 .bash_profile 将 重 新 用 该 文 件 原 来 设 置 的 PATH 变 量 的 值 来 初 始 化 PATH 变量 ( 稍 后 , 我 们 在 本 章 将 详 细 介 绍 .bash_profile 文 件 ) 。 如 果 你 想 保 存 你 新 增加 的 路 径 , 你 必 须 编 辑 你 的 .bash_profile 文 件 , 找 到 给 PATH 变 量 赋 值 的 地 方 , 然 后 只 需 往 PATH 变 量 中 插 入 “ : ” 号 及 新 的 路 径 至 路 径 列 表 中 即 可 。
PS1 和 PS2
PS1 和 PS2 变 量 分 别 用 来 设 置 系 统 首 选 和 辅 助 命 令 提 示 符 。 BASH Shell 的 首 选 命 令 提 示 符 是 符 号 “ $ ” , 你 可 以 用 新 的 字 符 ( 窜 ) 给 PS1 变 量 赋 新 的值 来 改 变 命 令 提 示 符 。 下 面 的 例 子 中 , Shell 命 令 提 示 符 由 符 号 “ $ ” 变 成 了 符号 “ -> ” 。
$ PS1="->"
->export PS1
->
你 可 以 把 命 令 提 示 符 设 置 成 任 何 你 想 设 置 的 符 号 , 包 括 字 符 串 。 如 下 例 :
$ PS1="Please enter a command: " P lease enter a command: export PS1 P lease enter a command: ls
mydata /reports
P lease enter a command:
PS2 变 量 用 来 设 置 辅 助 命 令 提 示 符 , 用 来 当 一 个 命 令 较 长 , 一 行 无 法 完 成或 没 有 完 成 时 , 系 统 在 下 一 行 给 用 户 的 命 令 提 示 符 。 缺 省 的 辅 助 命 令 提 示 符 是
“ > ” 。 当 一 行 无 法 完 成 或 没 有 完 成 时 , 后 续 增 加 的 命 令 行 将 用 辅 助 命 令 提 示 符而 不 是 首 选 命 令 提 示 符 。 你 可 以 通 过 上 述 改 变 首 选 命 令 提 示 符 的 方 法 来 改 变 辅助 命 令 提 示 符 的 值 。 例 如 :
$ PS2="@"
与 TCSH Shell 一 样 , BASH Shell 提 供 一 组 预 定 义 符 , 以 便 配 置 你 的 命 令提 示 符 。 你 可 以 用 时 间 、 你 的 用 户 名 或 者 你 的 当 前 目 录 路 径 名 , 甚 至 可 以 用 你当 前 将 要 输 入 命 令 的 历 史 事 件 号 作 为 你 的 命 令 提 示 符 或 提 示 符 的 一 部 分 。 每 个预 定 义 符 以 “ \ ” 符 号 开 头 。 “ \ w ” 代 表 当 前 的 工 作 目 录 , “ \ t” 代 表 当 前的 时 间 , “ \ u ” 代 表 你 的 用 户 名 。 “ \ !” 将 显 示 下 一 命 令 的 历 史 事 件 号 。 下面 的 例 子 中 , 用 户 在 命 令 提 示 符 中 增 加 了 当 前 工 作 目 录 。
$ PS1=" \ w $"
/home/dylan $
这 些 预 定 义 符 必 须 是 有 双 引 号 括 起 来 的 一 字 符 串 。 如 果 没 有 双 引 号 , 那 么这 些 预 定 义 符 将 不 会 被 赋 值 给 PS1 和 PS2 变 量 , 而 是 把 字 符 串 本 身 的 值 作 为命 令 提 示 符 。 例 如 命 令 行 PS1= \ w 将 把 字 符 串 “ \ w ” 设 置 为 命 令 提 示 符 , 而不 是 把 当 前 工 作 目 录 设 置 为 命 令 提 示 符 。 下 面 的 例 子 将 时 间 和 历 史 命 令 号 一 起作 为 新 的 命 令 提 示 符 。
$ PS1=" \ t \ ! ->"
下 面 是 一 些 用 来 配 置 系 统 命 令 提 示 符 的 一 组 预 定 义 符 列 表 :
\ !当 前 历 史 事 件 号
\ $ 除 超 级 用 户 外 , 所 有 的 其 它 用 户 都 用 “ $ ” 作 命 令 提 示 符 , 而 超级 用 户 用 “ # ” 作 命 令 提 示 符
\ d 当 前 日 期
\ s 当 前 Shell 类别
\ t 当 前 时 间
\ u 当 前 用 户 名
\ w 当 前 工 作 目 录
MAIL 、 MAILCHECK 及 MAILPATH
Linux 系 统 把 发 送 给 你 的 邮 件 保 存 在 用 户 邮 件 信 箱 文 件 里 , MAIL 变 量 就 是用 来 保 存 用 户 邮 件 信 箱 文 件 名 的 。 当 你 执 行 Mailx 实 用 程 序 时 , 等 待 你 阅 读 的邮 件 就 从 这 个 文 件 中 取 出 。 邮 件 信 箱 文 件 及 邮 件 实 用 程 序 在 本 书 第 8 章 有 详 细介 绍 。 尽 管 你 可 以 改 变 MAIL 变 量 的 值 , 但 一 般 很 少 或 没 有 必 要 改 变 它 。 Linux 系 统 需 要 这 个 目 录 路 径 名 去 寻 找 用 户 邮 件 信 箱 文 件 。
$ echo $MAIL
/var/mail/chris
MATLCHECK 变 量 用 来 设 置 时 间 间 隔 。 每 隔 这 个 设 定 的 时 间 间 隔 , 如 果 你有 新 邮 件 , 系 统 将 会 通 知 你 已 经 有 新 邮 件 。 如 果 你 希 望 系 统 一 收 新 邮 件 就 通 知你 , 你 可 以 减 少 这 一 时 间 间 隔 。 如 果 你 不 想 被 它 干 扰 , 你 可 以 延 长 这 一 时 间 间隔 。 缺 省 的 时 间 间 隔 是 10 分 钟( 600s ) 。 下 面 的 例 子 中 , 时 间 间 隔 被 设 置 成 20 分 钟 ( 1200s ) 。
$ MAILCHECK=1200
$ export MAILCHECK
如 果 你 想 在 检 查 另 外 一 些 邮 件 信 箱 文 件 的 来 件 情 况 ,你 可 以 设 置 MAILPATH 变 量 , 用 来 保 存 另 外 一 些 邮 件 信 箱 文 件 的 目 录 路 径 表 。与 MAIL 和 MAILCHECK 变 量 不 同 , MAILPATH 是 “ 用 户 级 定 义 ” ( user-defined ) 特 殊 变 量 。 要 使 用
该 变 量 , 你 必 须 给 它 赋 一 值 。 你 可 以 给 它 赋 值 任 何 你 想 核 查 的 邮 件 信 箱 文 件 的目 录 路 径 名 。 在 下 面 的 例 子 中 , 除 在 MAIL 变 量 中 指 定 的 邮 件 目 录 路 径 外 , 用户 还 指 定 了 另 外 一 需 要 检 查 来 件 情 况 的 邮 件 文 件 目 录 路 径 名 。
$ MAILPATH=/home/mail/$LOGNAME
$ export MAILPATH
BASH Shell “ 用 户 级 定 义 ” ( user-defined ) 特 殊 变 量
BASH Shell 中 用 户 级 特 殊 变 量 保 存 当 前 终 端 类 型 、 缺 省 的 vi 编 辑 器 配 置 等信 息 。 很 多 变 量 如 TERM 和 CDPATH 等 增 强 了 Shell 的 可 操 作 性 。 另 外 一 些是 为 某 些 特 定 的 实 用 程 序 设 定 的 。 例 如 EXINIT 变 量 就 是 用 来 配 置 vi 和 Ex 编 辑器 的 。 BASH Shell 环 境 下 的 一 些 可 重 定 义 变 量 和 用 户 级 定 义 变 量 在 表 15-2 中列 出 。
用 户 级 定 义 特 殊 变 量 不 是 系 统 定 义 的 。 如 果 你 要 使 用 它 们 , 你 自 己 必 须 定义 并 赋 值 给 它 们 。 三 个 常 见 的 用 户 级 定 义 特 殊 变 量 有 : CDPATH 、 TERM 和EXINIT 。 CDPATH 变 量 保 存 目 录 路 径 名 , 以 便 cd 命 令 方 便 地 寻 找 、 改 变 目 录 。TERM 变 量 保 存 当 前 使 用 的 终 端 类 型 。 EXINIT 变 量 用 来 配 置 vi 和 Ex 编 辑 器 命令 。
CDPATH
如 果 CDPATH 变 量 没 有 定 义 , 当 我 们 在 cd 命 令 后 给 出 目 录 名 作 参 数 时 , 它 仅 在 当 前 工 作 的 目 录 下 搜 索 所 给 出 的 目 录 名 。 但 是 , 如 果 定 义 了 CDPATH 变量 , 执 行 上 述 命 令 时 , 将 在 CDPATH 变 量 中 所 有 列 出 的 目 录 中 去 搜 索 。 如 果 该目 录 被 搜 索 到 , 运 行 cd 命 令 后 将 转 至 该 目 录 下 。 如 果 你 正 在 进 行 一 项 工 作 , 而
该 工 作 必 须 不 断 地 在 不 同 的 目 录 下 转 来 转 去 , 设 置 CDPATH 变 量 后 就 会 对 上 述工 作 非 常 有 用 。 要 转 至 和 你 现 在 目 录 差 别 很 大 的 目 录 路 径 下 , 你 必 须 知 道 该 目录 的 绝 对 路 径 。 但 是 , 你 只 需 简 单 地 将 要 转 向 的 目 录 路 径 的 父 路 径 增 加 到CDPATH 变 量 中 , cd 命 令 将 在 其 父 路 径 下 自 动 搜 索 , 为 你 找 到 你 所 要 转 向 的目 录 , 并 转 至 该 目 录 下 。 需 要 指 出 的 是 , 你 应 该 把 你 要 转 向 的 目 录 的 父 路 径 赋值 给 CDPATH 变 量 , 并 不 是 该 目 录 本 身 。
在 下 面 的 例 子 中 , CDPATH 被 增 加 了 搜 索 路 径 /home/chris/letters 。
/home/chris/letters 是 thankyou 的 父 目 录 。 当 执 行 带 参 数 thankyou 的 cd 命 令时 , CDPATH 中 的 目 录 将 自 动 搜 索 , 包 括 letters 目 录 , 于 是 , thankyou 目 录将 被 搜 索 到 。
$ CDPATH=$CDPATH:/home/chris/letters
$ export CDPATH
$ echo $CDPATH
:/home/chris/letters
$ cd thankyou
$ pwd
/home/chris/letters/thankyou
$
当 然 , 你 可 以 编 辑 .bash_profile 文 件 , 以 便 永 久 地 往 CDPATH 变 量 中 增 加一 些 目 录 路 径 名 。 本 书 建 议 在 向 CDPATH 变 量 中 增 加 新 的 目 录 路 径 名 的 过 程中 , 用 HOME 变 量 去 指 定 各 目 录 路 径 的 主 目 录 路 径 部 分 。 这 是 因 为 系 统 管 理 员在 对 文 件 系 统 进 行 重 新 组 织 的 过 程 中 , 你 的 主 目 录 路 径 有 可 能 改 变 。 HOME 变量 始 终 保 存 你 目 前 的 主 目 录 路 径 名 。 在 下 面 的 例 子 中 , 目 录 路 径 名
/home/chris/letters 是 用 $HOME/letters 指 定 的 。
$ CDPATH=$CDPATH:$HOME/letters
$ export CDPATH
$ echo $CDPATH
:/home/chris/letters TERM
TERM 变 量 保 存 目 前 你 使 用 的 终 端 的 终 端 名 。 如 果 你 是 从 一 个 终 端 登 陆 的 ,
系 统 将 询 问 你 的 终 端 名 , 你 所 输 入 的 终 端 名 将 被 保 存 在 变 量 TERM 中 。 一 些 应用 程 序 如 标 准 编 辑 器 , 将 通 过 TERM 变 量 来 查 明 你 所 使 用 的 终 端 类 别 , 这 样 , 系 统 才 正 确 映 射 键 盘 输 入 的 命 令 与 屏 幕 显 示 。 下 面 的 命 令 将 显 示 你 的 终 端 类 别 :
$ echo $TERM tvi925
如 果 你 想 改 变 你 的 终 端 类 别 , 你 可 以 给 TERM 变 量 赋 值 另 一 终 端 名 来 改 变它 。 在 下 面 的 例 子 中 , TERM 变 量 被 赋 值 以 vt100 终 端 类 型 , 然 后 , 用 输 出 变量 TERM , 以 使 在 使 用 Shell 的 过 程 中 都 能 访 问 它 。
$ TERM=vt100
$ export TERM
$ EXINIT
EXINIT 变 量 可 用 来 保 存 一 些 编 辑 器 的 命 令 选 项 , 这 些 命 令 选 项 可 以 用 来 配
置 vi 和 Ex 编 辑 器 的 编 辑 环 境 与 编 辑 命 令 。 当 你 启 动 这 些 编 辑 器 时 , EXINIT 变量 中 保 存 、 设 置 的 命 令 将 被 执 行 。 EXINIT 变 量 中 保 存 的 命 令 通 常 用 来 指 定 编 辑器 的 一 些 编 辑 特 性 , 如 是 否 显 示 行 号 、 是 否 进 行 行 缩 进 等 。 这 些 都 会 在 第 17 章
中 详 细 讨 论 。
在 下 面 的 例 子 中 , EXINIT 变 量 被 赋 值 给 一 个 set 命 令 , 该 set 命 令 用 来 设置 编 辑 器 显 示 行 号 及 自 动 缩 进 特 性 。 请 注 意 , 两 个 命 令 可 以 缩 写 并 合 并 为 一 个字 符 串 。
$ EXINIT='set nu ai'
$ export EXINIT
BASH Shell 登 陆 初 始 化 文 件 : .profile
.profile 文 件 是 BASH Shell 的 登 陆 初 始 化 文 件 , 该 文 件 名 也 可 以是 .bash_profile 。 它 是 一 个 脚 本 程 序 , 任 何 一 个 用 户 登 陆 进 入 BASH Shell 后 , 它 都 将 被 自 动 执 行 。 该 程 序 用 一 些 常 用 Shell 命 令 去 定 义 一 些 用 来 管 理 BASH Shell 的 特 殊 环 境 变 量 。 它 们 可 能 是 一 些 系 统 定 义 类 特 殊 环 境 变 量 的 重 定 义 或 一些 用 户 级 定 义 类 特 殊 变 量 。例 如 ,当 你 登 陆 进 入 系 统 ,用 户 Shell 必 须 知 道 Linux 系 统 的 一 些 系 统 命 令 所 在 的 目 录 。 Linux 系 统 将 根 据 PATH 变 量 所 指 定 的 目 录路 径 来 进 行 搜 索 。 但 是 , PATH 变 量 必 须 首 先 被 赋 与 指 定 的 目 录 路 径 名 。在 .bash_profile 中 , 有 一 个 赋 值 过 程 , 它 正 是 用 来 完 成 上 述 赋 值 操 作 的 。 由 于它 是 在 .bash_profile 中 , 这 一 赋 值 过 程 在 每 次 用 户 登 陆 时 都 被 自 动 执 行 。
也 有 一 些 特 殊 变 量 需 要 用 export 命 令 进 行 输 出 。 以 使 它 们 在 你 创 建 的 任 何
子 Shell 中 都 能 访 问 其 值 。 你 可 以 用 一 个 export 命 令 以 要 输 出 的 变 量 列 表 作 为参 数 同 时 输 出 几 个 变 量 。 通 常 在 .bash_profile 文 件 的 结 尾 用 一 个 export 命 令 输出 文 件 中 定 义 的 所 有 变 量 。 如 果 在 这 个 列 表 中 有 一 个 变 量 遗 漏 , 那 么 你 将 无 法访 问 该 变 量 。 请 大 家 注 意 下 面 .profile 文 件 结 尾 处 的 export 命 令 。
下 面 列 出 的 是 一 个 标 准 的 .bash_profile 文 件 的 拷 贝 , 这 个 文 件 会 在 你 的 用户 创 建 时 自 动 生 成 。 请 注 意 PATH 变 量 的 赋 值 情 况 ( 通 过 HOME 变 量 给 其 赋值 ) 。 PATH 变 量 和 HOME 变 量 都 是 系 统 定 义 的 特 殊 变 量 , 它 们 已 被 系 统 所 定义 。 PATH 变 量 中 保 存 目 录 的 路 径 名 , 在 执 行 任 何 输 入 的 命 令 时 都 要 对 这 些 目录 进 行 搜 索 , 而 HOME 变 量 保 存 你 的 主 目 录 路 径 名 。 赋 值 语 句PATH=$PATH:$HOME/bin 起 到 了 在 重 定 义 的 过 程 中 包 含 主 目 录 中 bin 的 目 录的 作 用 。 因 此 , 在 执 行 任 何 命 令 的 过 程 中 , 也 将 搜 索 你 的 bin 目 录 , 包 括 你 自己 定 义 的 脚 本 程 序 或 应 用 程 序 等 。 必 须 注 意 的 是 , PATH 必 须 用 export 命 令 进行 输 出 , 以 便 你 创 建 的 任 何 子 Shell 都 能 访 问 。 如 果 你 想 对 你 的 主 目 录 也 进 行搜 索 , 你 可 以 在 用 vi 或 Emacs 编 辑 器 修 改 .bash_profile 文 件 中 的 如 下 行 : PATH=$PATH:$HOME \ bin:$HOME , 在 上 述 行 的 末 尾 增 加 :$HOME 。 事 实 上 , 你 可 以 在 该 行 中 增 加 任 何 你 需 要 搜 索 的 目 录 名 。
.profile 文 件 清 单
#.bash_profile
#Get the aliases and functions if [ -f~/.bashrc ] ; then
.~/.bashrc
fi
#User-specific environment and startup programs
PATH=$PATH:$HOME/bin ENV=$HOME/.bashrc USERNAME=""
export USERNAME ENV PATH
Linux 系 也 有 其 自 己 的 profile 文 件 , 任 何 用 户 登 陆 进 入 用 户 时 , 它 都 会 执行 。 这 个 系 统 初 始 化 文 件 就 是 profile , 在 /etc 目 录 下 可 以 找 到 该 文 件
( /etc/profile ) , 里 面 包 含 了 系 统 提 供 给 每 个 用 户 的 一 些 特 殊 变 量 的 定 义 , 该 文件 的 清 单 在 下 面 列 出 。 请 注 意 , PATH 变 量 重 定 义 时 包 含 了 /usr/X11R6/bin 目录 。 该 目 录 路 径 包 含 了 X- W inodw 中 用 户 在 使 用 Ca ldera Desktop 时 要 执 行 的的 一 些 命 令 。 HISTFILE 也 被 重 定 义 , 它 被 赋 值 给 一 个 较 大 的 历 史 事 件 数 。
/etc/profile 文 件 清 单
# /etc/profile
# Systemwide environment and startup programs # Functions and aliases go in /etc/bashrc
PATH="$PATH:/usr/X11R6/bin" PS1= "[ \ u@ \ h \ W ] \ \ $"
ulimit -c 1000000
umask 002
HOSTNAME='/bin/hostname' H ISTSIZE=1000
H ISTFILESIZE=1000
#Default page for the arena browser
WWW_HOME=fi le:/usr/doc/Calderadoc-0.80-1/Caldera_Info #Default path for CRiSplite
CRPATH=/usr/lib/ CRiSplite/Macros
export PATH PS1 HOSTNMAE HISTSIZE HISTFILESIZE WWW_HOME CRPATH
if [ "$TERM"=conso l] then
M IM ICOM="-l -m -con -tmc"; export MINICOM
fi
初 始 化 文 件 , profile 是 一 个 文 本 文 件 , 你 可 以 用 任 何 一 个 文 本 编 辑 器 编 辑该 文 件 。 通 过 编 辑 .bash_profile 文 件 , 你 可 以 用 编 辑 命 令 把 一 个 新 的 目 录 路 径名 插 入 到 目 录 路 径 名 列 表 中 去 , 从 而 非 常 方 便 地 给 PATH 变 量 增 加 新 的 搜 索 路径 。 你 也 可 以 增 加 新 的 变 量 定 义 。 但 是 , 如 果 你 定 义 了 变 量 , 必 须 记 住 : 要 在export 命 令 的 参 数 列 表 中 增 加 你 所 定 义 的 变 量 名 。 例 如 , 如 果 你 的 .bash_profile 文 件 中 没 有 变 量 EXINIT 的 任 何 定 义 , 那 么 , 你 可 以 编 辑 该 文 件 , 并 增 加 新 的赋 值 语 句 给 EXINIT 变 量 赋 值 。 赋 值 语 句 EXINIT='set nu ai' 将 设 置 vi 编 辑 器 带行 号 及 自 动 缩 进 (indentation)。 然 后 , 你 需 将 EXINIT 变 量 增 加 到 export 命 令 的变 量 参 数 列 表 中 。 当 .bash_profile 再 一 次 被 运 行 时 , 变 量 EXINIT 将 被 赋 值 于命 令 行 set nu a i。 当 vi 编 辑 器 被 执 行 时 , 变 量 EXINIT 被 赋 值 的 命 令 行 将 被 执
行 , 从 而 将 编 辑 器 vi 自 动 设 置 成 带 行 号 , 并 进 行 自 动 缩 进 。
在 下 面 的 例 子 中 ,用 户 的 .bash_ profile 文 件 已 经 被 修 改 ,包 含 了 变 量 EXINIT 的 定 义 , 并 重 新 定 义 了 变 量 CDPATH 、 PS1 及 H ISTSIZE 。 变 量 H ISTSIZE 在重 定 义 时 , 其 保 存 的 历 史 事 件 号 减 少 了 , 由 系 统 .profile 文 件 中 定 义 的 1000 减少 到 30 ; 对 特 殊 变 量 PS1 的 重 定 义 , 使 系 统 提 示 符 包 括 了 当 前 的 工 作 目 录 。你 对 文 件 .bash_profile 中 特 殊 变 量 的 任 何 改 变 都 将 覆 盖 先 前 已 在 .profile 系 统 文件 中 定 义 的 特 殊 变 量 的 值 。 然 后 , 这 些 特 殊 变 量 需 用 export 命 令 进 行 变 量 输 出 。
.profile 文 件 清 单
# .bash_profile
# Get the aliases and functions if [ -f ~/.bashrc ] ; then
.~ /.bashrc
fi
#User-specific environment and startup programs PATH=$PATH:$HOME/bin:$HOME
ENV=$HOME/.bashrc USERNAME=""
CDPATH=$CDPATH:$HOME/bin:$HOME H ISTSIZE=30
EXINIT='set nu ai'
PS1= "\ w \ $"
export USERNAME ENV PATH CDPATH HISTSIZE EXINIT PS1
尽 管 .profile 文 件 在 你 每 次 登 陆 进 入 系 统 时 都 会 自 动 执 行 , 但 它 不 会 在 你 每次 修 改 就 自 动 运 行 。 因 此 , 登 陆 初 始 化 文 件 .profile 仅 仅 在 你 每 次 登 陆 时 才 会 自动 运 行 。 如 果 你 想 使 你 的 修 改 起 作 用 而 又 不 想 在 每 次 修 改 后 退 出 系 统 进 行 再 登陆 , 那 么 , 你 可 以 用 “ .” 命 令 运 行 .profile 文 件 。 .profile 文 件 是 一 个 Shell 脚 本程 序 , 和 其 它 Shell 脚 本 程 序 一 样 , 在 “ .” 命 令 后 键 入 .profile 就 可 以 运 行 该 文件 。
$ .profile
BASH Shell 初 始 化 文 件 : .bashrc
.bashrc 文 件 是 一 个 初 始 化 文 件 , 它 在 你 每 次 进 入 BASH Shell 或 创 建 一 新的 子 Shell 时 都 会 被 执 行 。 如 果 BASH Shell 是 你 的 登 陆 Shell, 那 么 , 在 你 登陆 时 , .bashrc 文 件 会 就 会 与 文 件 .bash_login 文 件 同 时 运 行 。 如 果 你 在 另 一 种Shell 下 进 入 BASH Shell , 则 .bashrc 文 件 会 自 动 运 行 , 文 件 中 的 一 些 变 量 与 别名 就 会 被 定 义 。
实 际 上 ,.bashrc Shell 初 始 化 文 件 在 你 每 次 创 建 一 个 Shell 时 ,都 会 被 执 行 。例 如 ,当 你 运 行 一 个 脚 本 Shell 程 序 时 。换 句 话 说 ,每 次 创 建 一 个 子 Shell ,.bashrc 文 件 就 会 被 执 行 。 这 时 , 在 .bashrc Shell 初 始 化 文 件 中 任 何 定 义 的 局 部 变 量 或别 名 , 在 用 export 命 令 进 行 变 量 输 出 后 , 都 会 起 作 用 。 .bashrc 文 件 中 通 常 是一 些 别 名 与 特 征 变 量 的 定 义 , 而 这 些 特 征 变 量 是 用 来 开 启 某 些 Shell 特 性 的 。
别 名 与 特 征 变 量 是 在 Shell 内 局 部 定 义 的 , 但 .bashrc 文 件 将 在 创 建 一 新 的 子Shell 中 定 义 它 们 。 因 此 , .bashrc 文 件 中 通 常 是 给 rm 、 cp 及 mv 等 命 令 定 义 的别 名 。 在 下 面 的 例 子 是 一 个 具 有 许 多 标 准 定 义 的 .bashrc 例 子 文 件 。
.bashrc 文 件 清 单
# Source global definitions if [ -f /etc/bashrc ] ; then
./etc/bashrc fi
set -o ignoreeof set -o noclobber
alias rm 'rm -i' alias mv 'mv -i' alias cp 'cp -i'
Linux 系 统 通 常 有 一 个 名 为 .bashrc 的 系 统 文 件 , 所 有 的 用 户 在 进 入 Shell 时 都 要 运 行 该 文 件 。 文 件 中 有 一 些 特 定 的 全 局 别 名 与 特 征 变 量 , 这 些 别 名 与 变量 对 任 何 进 入 BASH Shell 的 用 户 都 是 必 不 可 少 的 。 该 文 件 位 于 /etc 目 录 下
( /etc/.bashrc ) 。 用 户 自 己 的 .bashrc 文 件 位 于 用 户 主 目 录 下 , 该 文 件 中 包 含很 多 必 要 的 初 始 化 命 令 。 上 面 例 子 中 的 ./etc/bashrc 文 件 正 是 用 来 做 该 项 工 作的 。 你 可 以 在 你 自 己 的 .bashrc 文 件 中 定 义 你 自 己 的 命 令 或 定 义 。 如 果 你 修 改
了 .bashrc 文 件 , 且 希 望 它 们 能 在 当 前 的 登 陆 环 境 下 起 作 用 , 你 可 以 用 “ .” 命令 或 source 命 令 重 新 执 行 该 文 件 。
$ source .bashrc
BASH Shell 退 出 初 始 化 文 件 : .bash_logout
.bash_logout 也 是 一 个 初 始 化 文 件 , 当 用 户 退 出 系 统 时 , 将 执 行 该 文 件 。当 你 退 出 时 , 你 可 以 指 定 系 统 执 行 你 想 做 的 操 作 。 .bash_logout 文 件 不 是 用 来定 义 变 量 或 别 名 的 , 而 是 通 常 由 一 些 Shell 命 令 组 成 的 关 机 程 序 , 也 就 是 关 机时 你 想 要 系 统 做 的 一 些 操 作 。 通 常 希 望 系 统 退 出 时 的 操 作 是 清 屏 , 然 后 向 用 户发 出 祝 福 或 结 束 信 息 。
和 .bash_profile 文 件 一 样 , 你 可 以 在 .bash_logout 文 件 中 增 加 你 自 己 的 命令 。 实 际 上 , 在 你 的 用 户 被 创 建 时 , .bash_logout 并 不 能 自 动 建 立 。 你 需 用 vi 或 Emacs 编 辑 器 自 己 去 创 建 该 文 件 。 你 可 以 在 该 文 件 中 加 入 退 出 祝 福 语 或 其 它操 作 。 在 下 面 的 例 子 中 , 用 户 在 .bash_logout 文 件 中 加 入 clear 命 令 和 echo 命令 。 当 用 户 退 出 系 统 时 , clear 命 令 将 清 屏 , 然 后 显 示 “ Good-bye for now ” 信息 。
.bash_logout 文 件 清 单
clear
echo "Good-bye for now"
BASH Shell 程 序 设 计
BASH Shell 具 有 和 其 它 程 序 设 计 语 言 一 样 的 编 程 能 力 , 你 可 以 用 它 设 计 出复 杂 的 Shell 程 序 。 Shell 程 序 由 一 些 Linux 命 令 组 成 , 用 来 完 成 一 些 特 定 的 任务 。Linux Shell 能 提 供 许 多 编 程 工 具 给 用 户 ,用 户 可 以 利 用 这 些 工 具 来 创 建 Shell 脚 本 程 序 。 在 Shell 程 序 脚 本 中 , 你 可 以 定 义 变 量 并 赋 值 给 它 们 , 你 也 可 以 在脚 本 程 序 中 定 义 变 量 。 在 执 行 该 脚 本 程 序 时 , 用 户 还 可 以 通 过 交 互 式 方 式 给 这些 变 量 赋 值 ; Linux Shell 还 提 供 了 循 环 、 条 件 等 控 制 结 构 。 其 中 , 循 环 结 构 用来 多 次 执 行 某 些 Linux 命 令 ; 条 件 结 构 用 来 控 制 、 选 择 你 要 执 行 的 命 令 ;
你 还 可 以 建 立 算 术 或 比 较 操 作 表 达 式 。 所 有 这 些 程 序 设 计 语 句 及 控 制 结 构与 其 它 程 序 设 计 语 言 中 相 应 的 语 句 及 控 制 结 构 类 似 。 你 可 以 用 Shell 变 量 、 控制 结 构 、 表 达 式 及 Linux 命 令 来 进 行 Shell 程 序 设 计 。 通 常 由 这 些 组 成 shell 程序 的 指 令 编 写 成 可 以 单 独 运 行 的 脚 本 程 序 。 你 可 以 用 任 何 标 准 编 辑 器 来 创 建 这些 脚 本 文 件 。 要 运 行 该 Shell 程 序 , 你 只 需 执 行 该 脚 本 文 件 即 可 。 你 甚 至 可 以拆 分 到 几 个 脚 本 文 件 中 , 每 个 文 件 都 可 以 调 用 其 它 Shell 脚 本 程 序 。 可 以 把 变量 、 表 达 式 及 控 制 结 构 看 作 是 工 具 , 通 过 这 些 工 具 把 多 个 Linux 命 令 组 合 成 一个 命 令 。 从 这 种 意 义 上 说 , 一 个 Shell 程 序 是 用 户 创 建 的 新 的 、 复 杂 的 Linux 命令 。
15.8.1 Shell 脚 本 程 序 : 命 令 行 及 注 释 行
一 个 Shell 脚 本 程 序 是 一 个 由 Linux 命 令 组 成 的 文 本 文 件 , 你 可 以 用 任 何 文本 编 辑 器 来 编 辑 它 。 你 可 以 以 Shell 脚 本 程 序 的 文 件 名 作 参 数 , 用 sh 命 令 或“ .”
命 令 来 执 行 脚 本 程 序 中 的 命 令 。 你 也 可 以 设 置 文 件 的 属 性 为 “ 可 执 行 性 ”
( executable ) , 然 后 在 命 令 提 示 符 后 直 接 键 入 任 何 要 运 行 的 文 件 名 去 运 行 该脚 本 程 序 。 用 chmod 命 令 来 设 置 脚 本 程 序 的 可 执 行 性 属 性 , 可 以 把 脚 本 程 序 设置 成 可 执 行 文 件 。 在 用 chmod 命 令 修 改 文 件 的 可 执 行 性 属 性 时 , 可 以 用 绝 对 方式 或 符 号 方 式 。 用 符 号 方 式 “ u+x ” 可 修 改 文 件 的 可 执 行 性 属 性 , 例 如 命 令 行“ chmod u+x hello ” 将 把 脚 本 程 序 hello 设 置 成 可 执 行 性 。
然 后 , 你 可 以 直 接 运 行 脚 本 程 序 hello , 如 同 使 用 一 个 Linux 命 令 一 样 。 你只 需 设 置 文 件 的 可 执 行 性 属 性 一 次 。 一 旦 你 设 置 了 它 , 该 属 性 将 保 持 , 直 至 你改 变 其 这 一 属 性 为 止 。
hello 脚 本 程 序 清 单
echo "Hello, How are you"
$ chmod u+x hello
$ hello
Hello, how are you
在 用 绝 对 方 式 设 置 文 件 的 可 读 、 可 写 权 限 时 将 同 时 设 置 文 件 的 可 执 行 性 属性 。请 参 考 本 书 第 7 章 关 于 绝 对 方 式 与 符 号 方 式 的 详 细 解 释 与 说 明 。 简 要 地 说 , 700 将 把 文 件 设 置 成 可 写 、 可 读 及 可 执 行 权 限 , 500 将 仅 设 置 成 可 执 行 和 可 读权 限 , 300 设 置 成 可 执 行 和 可 写 权 限 , 400 将 只 具 有 可 执 行 权 限 。 通 常 用 户 将权 限 设 置 成 700 或 500 。 在 下 面 的 例 子 中 , 用 户 用 绝 对 方 式 将 文 件 hello 设 置成 可 执 行 权 限 。
$ chmod 750 hello
$ hello
hello, how are you
$
通 常 , 在 脚 本 文 件 中 用 简 短 的 解 释 来 说 明 文 件 的 功 能 、 特 定 命 令 与 变 量 的作 用 和 目 的 是 非 常 有 用 的 。 你 可 以 用 注 释 行 来 进 行 简 短 的 说 明 。 注 释 行 可 以 自成 一 行 或 是 文 本 行 的 一 部 分 , 注 释 内 容 前 必 须 用 符 号“ # ” 注 明 , 但 第 一 行 除 外 。注 释 行 以 换 行 符 为 结 束 , Shell 将 忽 略 任 意 行 上 符 号 “ # ” 后 的 字 符 。 Shell 脚 本程 序 的 第 一 行 是 保 留 行 , 用 来 识 别 创 建 的 Shell 类 型 ( 下 面 将 会 讨 论 到 )。 在 下 面的 例 子 中 , 描 述 脚 本 程 序 的 文 件 名 及 其 功 能 的 注 释 行 放 置 在 该 文 件 的 文 件 头 。
hello 脚 本 程 序 清 单
# The hello script says hello echo "Hello, how are you"
有 时 希 望 在 一 种 Linux Shell 下 运 行 为 另 一 种 Shell 编 写 设 计 的 脚 本 程 序 。假 设 你 目 前 在 TCSH Shell 下 , 而 想 运 行 一 个 为 BASH Shell 编 写 设 计 的 脚 本 程序 ( 该 脚 本 程 序 包 含 了 一 些 BASH Shell 命 令 ) , 首 先 , 你 必 须 用 sh 命 令 把 该Shell 脚 本 程 序 转 换 成 BASH Shell 脚 本 程 序 , 然 后 运 行 该 脚 本 程 序 , 最 后 在 转换 成 TCSH Shell 。 然 而 , 你 可 以 自 动 进 行 这 一 过 程 : 在 你 的 脚 本 程 序 的 首 行 键入 字 符 串 “ # !” , 然 后 键 入 你 系 统 的 Shell 程 序 的 路 径 名 。 Shell 始 终 首 先 检 查脚 本 程 序 的 最 初 一 个 字 符 , 以 辨 认 该 脚 本 程 序 是 BASH Shell 脚 本 程 序 还 是PDKSH Shell 脚 本 程 序 亦 或 TCSH Shell 脚 本 程 序 。 如 果 最 初 字 符 是 空 格 , 那么 , 该 脚 本 程 序 便 被 假 定 为 BASH Shell 脚 本 程 序 或 PDKSH Shell 脚 本 程 序 ; 如 果 只 是 单 独 的 “ # ” 号 (无 “ !” 号 ) , 该 脚 本 将 被 假 定 为 TCSH Shell 脚 本 程序 。 但 是 , 如 果 “ # ” 号 后 面 跟 着 字 符 “ !” , 那 么 , Shell 将 读 取 其 后 的 Shell 类 型 路 径 名 。 字 符 串 “ # !” 后 面 始 终 是 Shell 类 型 的 路 径 名 , 用 来 确 定 该 Shell 脚 本 程 序 运 行 的 Shell 类 型 。 如 果 你 目 前 在 与 某 脚 本 程 序 运 行 环 境 不 同 的 Shell
下 , 当 前 Shell 将 读 取 Shell 脚 本 程 序 中 Shell 的 路 径 名 , 并 转 换 至 该 Shell 下执 行 此 脚 本 程 序 。 但 此 时 如 果 其 初 始 字 符 是 空 格 或 “ # ” 号 , 当 前 Shell 将 无法 确 定 该 脚 本 程 序 是 BASH Shell 脚 本 程 序 还 是 TCSH Shell 脚 本 程 序 。 这 时 , 该 Shell 脚 本 程 序 将 仅 能 在 它 的 所 在 的 Shell 环 境 下 才 能 运 行 。如 果 你 想 让 Shell 辨 认 你 的 脚 本 程 序 的 Shell 类 别 ,你 必 须 在 字 符 串“ # !”后 面 键 入 你 所 运 行 的 Shell 类 型 。
例 如 , 如 果 你 在 脚 本 程 序 hello 的 首 行 键 入 字 符 串 “ #!/bin/sh ” , 你 就 可 以
在 TCSH Shell 中 直 接 运 行 该 脚 本 程 序 。运 行 时 ,系 统 首 先 将 改 变 到 BASH Shell 下 , 然 后 执 行 该 脚 本 程 序 的 命 令 , 然 后 返 回 TCSH Shell 或 任 意 执 行 该 脚 本 时的 Shell 。 在 下 面 的 例 子 中 , hello 脚 本 程 序 输 入 了 “ #!/bin/sh ” 命 令 , 然 后 用 户可 以 在 TCSH Shell 中 执 行 该 脚 本 程 序 。
hello 脚 本 程 序 清 单
#!/bin/sh
# The hello script says hello echo "Hello, how are you"
- hello
Hello, how are you
变 量 与 脚 本 程 序
在 Shell 中 , 你 可 以 用 变 量 及 脚 本 语 句 来 创 建 Shell 程 序 。 在 Shell 脚 本 程序 中 , 你 可 以 定 义 变 量 并 给 它 们 赋 值 。 变 量 定 义 在 本 书 第 5 章 已 详 细 讨 论 过 。由 于 变 量 定 义 在 Shell 程 序 设 计 过 程 中 非 常 有 用 , 作 者 在 这 将 会 简 要 介 绍 。
在 Shell 脚 本 程 序 的 输 入 、 输 出 操 作 中 , 变 量 使 用 的 非 常 多 。 read 命 令 允许 用 户 交 互 式 地 给 一 个 变 量 赋 值 。 当 需 要 用 户 进 行 数 据 输 入 时 , 程 序 设 计 者 通常 会 给 用 户 一 个 提 示 去 通 知 用 户 。 另 一 种 脚 本 程 序 数 据 输 入 方 式 称 之 为 Here 文 件 方 式 , 它 允 许 你 为 程 序 中 的 命 令 提 供 多 行 输 入 。 该 数 据 输 入 方 式 克 服 了 总需 要 通 过 读 取 外 部 文 件 等 方 式 来 进 行 多 行 数 据 输 入 。
变 量 的 定 义 与 赋 值 : = 、 $ 、 set 及 unset
在 Shell 中 , 当 你 首 次 使 用 变 量 的 名 字 的 时 候 , 需 要 对 一 变 量 进 行 声 明 。 变量 的 名 字 可 以 是 任 何 一 组 字 母 组 成 的 字 符 或 字 符 串 , 包 括 下 划 线 。 变 量 名 也 可以 包 含 数 字 , 但 数 字 不 能 作 为 变 量 的 第 一 个 字 母 。 变 量 名 中 不 能 有 如 下 字 符 , 如 “ !” 号 、 “ & ” 字 符 及 空 格 等 。 有 些 变 量 是 Shell 保 留 的 , 只 能 被 Shell 自 己使 用 。 变 量 名 也 不 能 包 含 几 个 英 文 单 词 , 因 为 系 统 要 使 用 空 格 去 对 命 令 进 行 句法 分 析 , 并 用 它 分 隔 命 令 名 及 其 参 数 。
你 可 以 用 赋 值 操 作 给 一 个 变 量 赋 值 :键 入 变 量 的 名 ,然 后 键 入 赋 值 操 作“ = ”, 再 键 入 相 关 数 据 , 变 量 将 被 赋 值 。 需 指 出 的 是 , 赋 值 操 作 语 句 中 不 能 有 任 何 空格 。 任 何 一 组 字 符 串 都 可 以 赋 值 给 一 个 变 量 。 在 下 面 的 例 子 中 , 变 量 greeting 被 赋 以 字 符 串 “ Hello ”。
$ greeting="Hello"
一 旦 你 给 一 个 变 量 赋 值 , 你 就 可 以 使 用 该 变 量 , 并 引 用 它 的 值 。 通 常 我 们引 用 变 量 的 值 作 为 一 个 命 令 的 参 数 。 你 可 以 在 变 量 前 面 加 美 元 字 符 “ $ ” 来 引 用变 量 的 值 。 “ $ ” 字 符 是 一 个 特 殊 操 作 符 , 它 用 变 量 的 名 来 引 用 变 量 的 值 。 该 引用 将 导 致 命 令 行 上 的 变 量 名 被 一 组 字 符 窜 所 代 替 。这 样 , 任 何 在 变 量 名 前 有“ $ ” 字 符 的 地 方 , 变 量 名 将 由 变 量 的 值 所 代 替 。
$ echo $greeting Hello
你 可 以 用 set 命 令 来 列 出 所 有 已 定 义 的 变 量 的 列 表 。 如 果 你 认 为 不 再 需 要 某变 量 , 可 用 unset 命 令 来 删 除 该 变 量 。
说 明 : 表 15-3 列 出 了 一 些 常 用 的 BASH Shell 命 令 及 其 命 令 参 数 与 功 能 , 如 echo 、 read 及 break 等 。
变 量 值 : 字 符 串
你 赋 值 给 变 量 的 值 可 能 是 由 一 组 字 符 组 成 的 字 符 串 。 这 些 字 符 可 能 是 你 直接 输 入 的 , 也 有 可 能 是 你 执 行 一 个 Linux 命 令 后 的 得 到 的 结 果 。 大 多 数 情 况 下 , 你 需 要 用 单 引 号 、 双 引 号 、 反 斜 扛 号 及 回 引 号 等 去 引 用 这 些 变 量 的 值 。 单 引 号 、双 引 号 、 反 斜 扛 及 回 引 号 能 让 用 户 以 不 同 的 方 式 引 用 字 符 串 的 值 。 回 引 号 “ '” 的 特 殊 功 能 在 于 : 当 执 行 一 个 Linux 命 令 时 , 它 同 时 把 执 行 的 结 果 作 为 命 令 行上 的 一 个 命 令 行 参 数 。
字 符 串 引 用 : 双 引 号 、 单 引 号 和 反 斜 扛
尽 管 字 符 变 量 的 值 可 以 由 任 何 字 符 串 组 成 , 但 当 你 在 字 符 串 中 包 含 了 一 些特 殊 字 符 , 而 这 些 特 殊 字 符 又 是 被 Shell 作 为 操 作 算 子 的 , 这 时 脚 本 程 序 就 可能 会 出 现 问 题 。 Shell 有 一 类 特 殊 的 字 符 , 它 们 可 以 被 用 在 命 令 行 赋 值 中 。 星号 “ * ” 、 问 号 “ ? ” 、 括 号 “ ( ” 及 “ ) ” 等 都 是 一 组 特 殊 字 符 , 这 些 特 殊 字符 可 以 实 现 文 件 名 扩 展 。 此 外 , 特 殊 字 符 “ .” 代 表 当 前 的 目 录 , “ $ ” 代 表 变量 的 值 , 大 于 符 “ > ” 及 小 于 符 “ < ” 是 重 定 向 操 作 算 子 , 符 号 “ & ” 用 来 执 行后 台 命 令 , 而 符 号 “ |” 表 示 通 过 管 道 输 出 执 行 的 结 果 。 如 果 你 想 使 用 上 述 特 殊字 符 作 为 你 变 量 值 的 一 部 分 , 你 必 须 首 先 引 用 它 们 。 在 命 令 行 上 引 用 一 个 特 殊变 量 字 符 时 , 它 不 会 被 Shell 解 释 为 一 个 特 殊 字 符 。
单 引 号 及 双 引 号 允 许 你 同 时 引 用 几 个 特 殊 变 量 , 任 何 在 单 引 号 及 双 引 号 内的 特 殊 字 符 都 会 被 引 用 。 一 个 反 斜 扛 只 引 用 单 个 字 符 ( 其 前 面 的 字 符 ) 。 如 果你 想 把 多 个 单 词 赋 值 给 一 个 变 量 , 你 需 用 单 引 号 去 把 那 些 用 空 格 定 界 的 单 词 括起 来 ( 你 也 可 以 用 双 引 号 ) , 认 为 是 把 一 个 字 符 串 赋 值 给 了 一 个 变 量 。 当 然 , 任 何 在 双 引 号 内 的 特 殊 字 符 也 会 被 引 用 。
下 面 的 例 子 用 三 种 方 法 去 给 字 符 类 型 变 量 赋 值 。 在 第 一 个 例 子 中 , 用 把 双引 号 内 用 空 格 定 界 的 单 词 赋 值 给 变 量 notice 。 由 于 空 格 是 在 双 引 号 内 的 , 因 此 , 它 们 被 认 为 是 普 通 的 字 符 , 而 不 是 Shell 用 来 分 割 命 令 行 参 数 的 定 界 符 。 在 第二 个 例 子 中 , 单 引 号 内 的 字 符 串 也 被 赋 值 给 变 量 message , 特 殊 字 符 “ .” 被 认为 是 一 个 普 通 的 字 符 。 在 第 三 个 例 子 中 , 星 号 “ * ” 特 殊 字 符 被 括 在 双 引 号 内 , 该 字 符 也 被 认 为 是 字 符 串 内 的 一 个 普 通 字 符 , 而 Shell 不 会 认 为 它 是 一 个 通 配符 。
$ notice="The meeting will be tomorrow"
$ echo $notice
The meeting will be tomorrow
$ message='The project is on time.'
$ echo $ message The project is on time.
$ notice="You can get a list of files with ls *.c"
$ echo $notice
You can get a list of files with ls *.c
但 是 , 双 引 号 中 的 特 殊 字 符 “ $ ” 不 会 被 赋 值 给 变 量 , 该 特 殊 字 符 用 来 引 用变 量 的 值 。 在 双 引 号 内 的 “ $ ” 字 符 后 的 变 量 仍 然 将 代 表 该 变 量 的 值 , 而 该 变 量的 值 将 成 为 字 符 串 的 一 部 分 , 而 不 是 变 量 名 成 为 字 符 串 的 一 部 分 。 在 双 引 号 内你 可 以 使 用 该 方 法 来 引 用 多 个 变 量 的 值 。 在 下 面 的 例 子 中 , 变 量 winner 的 值 将被 notice 变 量 引 用 。
$ winner=dylan
$ notice="The person who won is $ winner"
$ echo $notice
The person who won is dylan
另 一 方 面 , 如 果 你 也 不 想 在 双 引 号 内 引 用 一 个 变 量 的 值 , 你 可 以 用 单 引 号来 把 赋 值 的 字 符 窜 括 起 来 。 此 时 , 单 引 号 将 忽 略 字 符 串 内 的 任 何 引 用 , 而 把 特
殊 字 符 “ $ ” 仅 看 作 为 一 个 普 通 的 字 符 。 在 下 面 的 例 子 中 , 单 引 号 忽 略 了 其 内 的变 量 winner 的 引 用 。
$ winner=dylan
$ result='The name is the $winner variable'
$ echo $result
The name is the $winner variable
此 时 , 如 果 用 的 是 双 引 号 , 那 么 , 变 量 winner 的 值 将 会 被 变 量 result 引 用 。看 下 面 的 例 子 : 字 符 串 “ $winne r” 被 变 量 winner 的 值 替 换 。
$ winner=dylan
$ result="The name is the $winner variable"
$ echo $result
The name is the dylan variable
你 可 以 用 反 斜 扛 特 殊 字 符 “ \ ” 来 在 字 符 串 中 使 用 任 何 特 殊 字 符 , 包 括 特殊 字 符 “ $ ” 。 当 你 在 赋 值 的 字 符 串 中 同 时 包 括 变 量 值 引 用 及 普 通 字 符 “ $ ” 时 , 你 必 须 用 到 反 斜 扛 字 符 “ \ ” 。 在 下 面 的 例 子 中 , 为 了 把 特 殊 字 符 “ $ ” 看 作 一个 普 通 的 美 元 字 符 , 你 可 以 在 其 前 面 输 入 一 反 斜 扛 字 符 , 及 用 字 符 串 “ \ $ ” 表示 。 同 时 , 由 于 字 符 串 是 用 双 引 号 括 起 来 的 , 因 此 , $winner 将 引 用 变 量 winner 的 值 。
$ winner=dylan
$ result="$winner won \ $100.00"
$ echo $reuslt dylan won $100.00
Linux 命 令 的 值 : 回 引 号 “ '” ( back qutoes )
尽 管 你 可 以 通 过 定 义 字 符 或 字 符 串 变 量 来 引 用 变 量 的 值 , 你 还 可 以 直 接 把Linux 命 令 的 运 行 结 果 赋 值 给 变 量 。 但 是 , 如 果 你 要 把 Linux 命 令 的 运 行 结 果 赋值 给 变 量 , 你 必 须 首 先 运 行 该 命 令 。 如 果 你 在 命 令 行 上 输 入 Linux 命 令 , 该 命令 首 先 将 会 被 执 行 , 它 的 执 行 结 果 将 成 为 命 令 行 的 一 个 参 数 。 如 果 把 将 要 首 先运 行 的 Linux 命 令 放 置 在 回 引 号 内 , 命 令 的 运 行 结 果 将 被 赋 值 给 变 量 。 我 们 也可 以 把 回 引 号 看 作 是 一 个 表 达 式 , 而 该 表 达 式 是 包 含 了 一 个 将 要 运 行 的 Linux 命 令 及 其 运 行 的 结 果 。
在 下 面 的 例 子 中 , 命 令 ls *.c 首 先 将 被 执 行 , 而 其 运 行 结 果 将 被 赋 值 给 变 量listc。 命 令 ls *.c 用 来 列 出 所 有 扩 展 名 为 .c 的 文 件 , 然 后 , 这 个 文 件 名 列 表 将 被赋 值 给 变 量 listc 。
$ listc='ls *.c'
$ echo $listc main.c prog.c lib.c
必 须 注 意 回 引 号 与 单 引 号 之 间 的 区 别 : 单 引 号 把 一 个 Linux 命 令 看 作 是 一组 字 符 串 , 而 回 引 号 将 表 示 它 是 一 个 Linux 命 令 , 并 会 执 行 这 个 Linux 命 令 。有 时 , 你 可 能 在 想 要 使 用 回 引 号 时 无 意 间 输 入 了 单 引 号 。 下 面 的 两 个 例 子 说 明了 两 者 之 间 的 区 别 。 对 于 第 一 个 例 子 , 赋 值 给 变 量 lscc 的 值 是 用 单 引 号 而 不 是回 引 号 , 此 时 , “ ls *.c ” 仅 被 看 作 是 一 个 字 符 串 赋 值 给 变 量 lscc 。 对 于 第 二 个例 子 , 字 符 串 “ ls *.c ” 是 用 回 引 号 括 起 来 的 , 因 此 , 该 命 令 将 会 被 执 行 。 于 是 , 所 有 那 些 以 .c 为 扩 展 名 的 文 件 名 生 成 一 个 文 件 名 列 表 , 然 后 该 文 件 名 列 表 被 赋
值 给 变 量 lscc 。
$ lscc='ls *.c'
$ echo $lscc ls *.c
$ lscc='ls *.c'
$ echo $lscc main.c prog.c
引 用 命 令 : 单 引 号
有 时 , 你 可 能 会 在 一 个 Linux 命 令 上 使 用 单 引 号 。 在 Linux 命 令 上 使 用 单 引号 可 以 使 你 把 一 个 Linux 命 令 赋 值 给 一 个 变 量 , 此 时 , 你 可 以 把 该 变 量 作 为 该Linux 命 令 的 另 外 一 个 名 字 。 如 果 在 命 令 行 上 输 入 该 变 量 的 名 之 前 键 入 操 作 算子 “ $ ” , 该 变 量 所 代 表 的 Linux 命 令 将 被 执 行 。 在 下 面 的 例 子 中 , Shell 变 量被 赋 值 以 Linux 命 令 ls -F , 必 须 注 意 命 令 上 的 单 引 号 。 当 Shell 变 量 在 命 令 行上 被 赋 值 的 时 候 , 包 含 该 命 令 的 变 量 将 成 为 一 个 命 令 行 参 数 , 且 其 包 含 的 命 令将 会 被 执 行 。
$ lsf='ls -F'
$ $lsf
mydata /report/letters
$
实 际 上 , 与 别 名 命 令 类 似 , 该 变 量 是 你 为 Linux 命 令 创 建 的 另 外 一 个 名 字 。在 余 下 的 章 节 中 可 以 看 到 , 在 特 定 的 Shell 环 境 下 , 你 可 以 用 一 个 特 别 的 别 名
命 令 来 完 成 上 述 操 作 。
脚 本 输 入 与 输 出 命 令 : echo 、 read 及 <<
在 一 个 脚 本 程 序 中 , 你 可 以 使 用 echo 命 令 来 输 出 数 据 , 而 用 read 命 令 来读 取 输 入 数 据 给 变 量 。 此 外 , 你 还 可 以 使 用 Here 文 件 来 在 脚 本 中 指 定 数 据 , 并 把 它 们 重 定 向 给 一 个 命 令 。
在 脚 本 程 序 中 , echo 命 令 可 以 把 数 据 送 到 标 准 输 出 , 这 些 数 据 可 能 是 以 字符 串 形 式 输 出 的 字 符 。 你 将 会 发 现 , echo 命 令 可 以 输 出 变 量 的 值 , 也 可 以 输 出常 量 字 符 串 。
read 命 令 可 以 从 终 端 上 读 取 一 行 输 入 数 据 , 并 赋 值 给 一 个 或 多 个 变 量 。 该命 令 可 以 使 用 户 交 互 式 地 给 变 量 赋 值 。 的 直 至 换 行 符 的 任 何 字 符 都 将 被 读 入 , 并 把 这 些 读 入 的 字 符 赋 值 给 变 量 。 在 Shell 程 序 中 , 你 可 以 一 起 使 用 echo 命 令与 read 命 令 , 以 便 提 示 用 户 输 入 数 据 , 输 入 数 据 后 , read 命 令 将 把 读 入 的 数据 赋 值 给 变 量 。 在 下 面 的 greetvar 脚 本 程 序 中 , 用 户 被 提 示 输 入 数 据 给 变 量greeting , 然 后 , read 命 令 读 取 用 户 键 入 的 数 据 , 并 赋 值 给 变 量 greeting。
greetvar 脚 本 程 序 清 单 :
echo Pease enter a greeting:
read greeting
echo "The greeting you enter was $greeting"
$ greetvar
P lease enter a greeting:
Hi
The greeting you enter was Hi
$
当 处 理 用 户 的 输 入 时 , 你 必 须 考 虑 到 用 户 有 可 能 输 入 Shell 特 殊 字 符 。Linux 命 令 中 的 任 何 特 殊 字 符 , 无 论 它 是 在 脚 本 程 序 还 是 在 其 它 地 方 , 该 特 殊 字 符 都将 被 引 用 , 除 非 它 们 被 引 号 括 起 来 。 如 果 一 个 变 量 的 值 是 一 个 特 殊 字 符 , 且 变量 的 值 是 用 $ 来 引 用 的 , 那 么 , Shell 将 认 为 是 一 个 特 殊 字 符 , 并 把 它 用 变 量 的值 代 替 。 在 脚 本 程 序 greetvar 程 序 中 , $greeting 被 放 置 在 一 个 被 引 号 括 起 来 的字 符 串 中 , 从 而 可 以 使 用 特 殊 字 符 “ $ ” 来 求 变 量 greeting 的 值 。 否 则 , 如 果
$greeting 所 在 的 字 符 串 没 有 被 用 括 号 括 起 来 , 那 么 , 特 殊 字 符 的 意 义 将 被 扩 展 。有 时 , 你 也 希 望 那 些 特 殊 字 符 被 扩 展 , 例 如 , 你 想 列 出 所 有 以 用 户 输 入 的 字 符为 前 缀 的 文 件 时 , 此 时 , 用 户 输 入 的 任 何 特 殊 字 符 的 意 义 都 需 被 扩 展 。 在 下 面的 例 子 中 , 脚 本 程 序 中 的 特 殊 字 符 “ *” 被 扩 展 , 以 显 示 以 扩 展 名 为 .c 的 所 有 文件 。 请 注 意 $fref 没 有 被 双 引 号 括 起 来 。
listfile 脚 本 程 序 清 单 :
echo Please enter a file reference: read fref
echo The files you request are: $fref
$listfiles
P lease enter a file reference:
*.c
The files you request are: calc.c lib.c main.c
通 常 情 况 下 , Shell 脚 本 程 序 包 含 一 系 列 的 Linux Shell 命 令 , 但 有 时 , 你可 能 需 要 把 输 入 的 数 据 作 为 一 个 命 令 的 参 数 , 例 如 , 如 果 你 想 把 多 行 数 据 输 入给 Shell 脚 本 程 序 中 的 某 个 命 令 。 Here 操 作 可 以 达 到 上 述 目 的 。 Here 操 作 是 一个 重 定 向 操 作 , 用 来 把 Shell 脚 本 中 读 入 的 数 据 重 定 向 给 一 个 命 令 。 它 之 所 以称 为 Here 操 作 是 因 为 重 定 向 数 据 是 来 自 脚 本 程 序 ,而 不 是 来 自 其 它 的 文 件 。Here 操 作 用 两 个 小 于 号 “ << ” 来 表 示 。 “ << ” 操 作 可 以 认 为 是 一 个 重 定 向 操 作 , 它用 来 把 脚 本 程 序 中 的 数 据 输 入 给 一 个 命 令 。 “ << ” 操 作 算 子 放 置 在 它 要 被 重 定向 的 命 令 之 后 , “ << ” 后 的 输 入 数 据 将 被 认 为 是 输 入 给 命 令 的 数 据 。 你 可 以 用CTRL-d 操 作 来 结 束 数 据 输 入 。 你 也 可 以 不 使 用 CTRL-d 而 用 自 己 指 定 的 一 个结 束 符 来 结 束 本 次 数 据 输 入 , 这 时 , 在 同 一 行 上 、 “ << ” 操 作 算 子 之 后 的 单 词将 被 认 为 是 本 次 数 据 输 入 的 结 束 符 。 该 结 束 符 可 以 是 任 何 符 号 。 所 有 至 结 束 符之 前 的 数 据 行 都 将 被 作 为 其 重 定 向 命 令 的 输 入 。
在 下 面 的 例 子 中 , 一 些 信 息 被 发 送 给 用 户 mark , 其 中 , 发 送 的 信 息 来 自 于
Here 操 作 。 本 次 Here 操 作 使 用 的 结 束 符 是 单 词 “ myend ” 。
mailmark 脚 本 程 序 清 单 :
mail mark << myend
D id you remember the meeting Robert
myend
脚 本 程 序 命 令 行 参 数
与 Linux 命 令 一 样 , 一 个 Shell 脚 本 程 序 也 可 以 有 其 运 行 参 数 。 当 你 启 动 一个 脚 本 程 序 时 , 你 可 以 在 命 令 行 上 键 入 脚 本 程 序 名 , 然 后 输 入 运 行 该 脚 本 程 序的 一 些 运 行 参 数 。 你 可 以 在 脚 本 程 序 中 用 “ $ ” 操 作 算 子 及 其 在 命 令 行 上 的 参 数序 号 来 引 用 这 些 参 数 。 命 令 行 上 的 参 数 按 顺 序 从 1 开 始 编 号 , 第 一 个 参 数 可 以用 “ $1 ” 来 引 用 , 而 其 第 二 个 参 数 可 以 用 “ $2 ” 来 引 用 , 依 此 类 推 。 “ $0 ” 将引 用 该 命 令 行 上 的 第 一 个 字 符 , 即 Shell 脚 本 程 序 名 本 身 。
所 有 对 这 些 参 数 的 引 用 都 可 以 被 认 为 是 对 只 读 变 量 的 值 的 引 用 。 如 果 你 比
较 熟 悉 程 序 设 计 语 言 中 的 术 语 , 那 么 , 你 可 以 把 命 令 行 上 的 参 数 认 为 是 系 统 赋值 给 参 数 变 量 $1 及 $9 等 的 值 , 而 参 数 变 量 在 脚 本 程 序 运 行 的 过 程 中 是 只 读 的 , 你 不 能 再 给 它 们 赋 值 。 一 旦 系 统 给 它 们 赋 初 值 后 , 你 不 能 再 改 变 这 些 参 数 变 量的 值 。 从 这 种 意 义 上 说 , 参 数 变 量 更 像 常 数 , 这 些 常 数 是 由 命 令 行 参 数 确 定 的 。除 非 被 引 号 括 起 来 , 命 令 行 上 的 每 一 个 单 词 将 会 被 认 为 是 命 令 行 上 一 个 独 立 的参 数 。 如 果 你 在 命 令 行 上 输 入 了 多 个 参 数 , 那 么 , 可 以 用 相 应 的 参 数 号 来 引 用它 们 。 在 下 面 的 例 子 中 , 命 令 行 上 输 入 了 四 个 参 数 。
greetargs 脚 本 程 序 清 单 :
echo "The first argument is: $1" echo "The second argument is: $2" echo "The third argument is: $3" echo "The fourth argument is: $4"
$ greetargs Hello Hi Salutation "How are you" The first argument is:Hello
The second argument is: Hi
The third argument is:Salutation The fourth argument is:How are you
你 可 以 用 一 组 特 殊 字 符 以 各 种 方 式 去 引 用 命 令 行 上 的 命 令 参 数 ,例 如“ $ *”、“ $@ ” 及 “ $# ” 等 。 其 中 , “ $# ” 代 表 命 令 行 上 的 参 数 个 数 , 这 在 为 一 个 脚本 程 序 指 定 固 定 的 参 数 数 目 时 很 有 用 。“ $* ” 用 来 代 表 命 令 行 上 的 所 有 参 数( 在一 个 命 令 行 上 可 以 有 多 达 9 个输入参数) 。“ $@ ” 也 代 表 命 令 行 上 的 所 有 参 数 , 但 它 可 以 使 你 单 独 引 用 所 有 命 令 行 参 数 中 的 每 个 参 数 。 “ $ *” 与 “ $@ ” 命 令 之间 的 区 别 不 是 很 明 显 , 但 当 你 使 用 for-in 控 制 结 构 引 用 命 令 行 参 数 时 , 你 就 可以 很 好 地 理 解 它 们 之 间 的 差 别 。 因 此 , 本 节 将 对 这 些 特 殊 参 数 只 作 简 要 介 绍 , 在 本 章 后 面 的 控 制 结 构 中 将 有 更 详 细 的 介 绍 。
在 下 面 的 例 子 中 , 命 令 行 参 数 先 后 被 用 特 殊 变 量 “ $* ” 及 “ $@ ” 显 示 在 屏幕 上 。 命 令 行 上 的 参 数 数 量 被 特 殊 变 量 “ $# ” 显 示 在 屏 幕 上 。
sargs 脚 本 程 序 清 单 :
echo $* echo $@
echo "There are $# arguments"
$ sargs Hello Hi W elcome Hello Hi W elcome
Hello Hi W elcome There are 3 arguments
输 出 变 量 与 脚 本 Shell
当 你 执 行 一 个 脚 本 程 序 的 时 候 , 你 将 初 始 化 一 个 新 的 进 程 , 而 该 进 程 有 其自 己 的 Shell 。 在 该 进 程 的 Shell 中 , 你 可 以 自 己 定 义 变 量 、 执 行 Linux 命 令 , 甚 至 执 行 其 它 的 脚 本 程 序 。 如 果 你 在 当 前 正 在 运 行 的 脚 本 程 序 中 执 行 另 一 个 脚本 程 序 , 那 么 , 当 前 正 在 被 执 行 的 脚 本 程 序 将 被 挂 起 , 系 统 控 制 被 转 换 到 执 行的 另 一 个 脚 本 程 序 上 , 在 返 回 到 被 挂 起 的 脚 本 程 序 之 前 , 此 脚 本 程 序 中 的 所 有的 命 令 都 将 首 先 被 执 行 , 然 后 再 返 回 至 被 挂 起 的 脚 本 程 序 中 继 续 执 行 。
从 一 个 脚 本 程 序 中 执 行 另 一 个 脚 本 程 序 的 过 程 与 程 序 设 计 语 言 中 的 函 数 或
过 程 调 用 很 相 似 。 你 可 以 认 为 是 一 个 脚 本 程 序 在 调 用 另 一 个 脚 本 程 序 , 直 到 被调 用 的 脚 本 程 序 执 行 结 束 后 , 调 用 该 程 序 的 脚 本 程 序 才 开 始 继 续 执 行 其 余 下 的命 令 。
任 何 在 你 脚 本 程 序 中 定 义 的 变 量 都 会 在 它 对 应 的 脚 本 Shell 中 定 义 , 这 些 定义 的 变 量 只 是 局 部 变 量 , 它 只 在 它 自 己 的 Shell 中 起 作 用 。 从 这 种 意 义 上 说 , 有 些 变 量 是 被 隐 藏 在 它 们 自 己 的 Shell 之 中 。 但 是 , 有 时 你 希 望 在 脚 本 程 序 中定 义 的 变 量 可 以 在 其 调 用 的 任 何 脚 本 程 序 中 起 作 用 。 虽 然 你 不 能 直 接 定 义 这 样的 变 量 , 但 你 可 以 用 exort 命 令 把 你 定 义 的 变 量 输 出 到 另 外 一 个 脚 本 程 序 中 。当 你 用 export 命 令 输 出 一 个 变 量 时 , 该 命 令 将 告 诉 系 统 在 每 个 新 创 建 的 子 Shell 中 都 定 义 一 个 该 变 量 的 拷 贝 。 于 是 每 个 新 创 建 的 子 Shell 都 可 以 有 该 输 出 变 量的 拷 贝 。在 下 面 的 例 子 中 , 变 量 myname 被 定 义 , 特 殊 也 被 用 export 命 令 输 出 。
$ myname="Charles"
$ export myname
通 常 有 的 读 者 把 输 出 变 量 理 解 为 全 局 变 量 , 这 种 理 解 实 际 上 是 错 误 的 。 一
个 Shell 决 不 会 引 用 一 个 在 其 外 部 定 义 的 变 量 。 如 果 在 一 个 Shell 内 输 出 了 一 个变 量 , 在 创 建 新 Shell 时 , 系 统 只 是 在 其 子 Shell 中 生 成 了 该 输 出 变 量 的 值 的 一个 拷 贝 , 即 输 出 变 量 只 输 出 它 们 的 值 , 而 不 是 该 变 量 本 身 。 从 某 种 程 度 上 说 , 一 个 输 出 变 量 是 一 个 限 定 范 围 内 的 全 局 参 数 ( a scoped global paramete r) , 系 统 会 把 该 变 量 的 值 拷 贝 至 在 该 Shell 上 创 建 的 任 何 子 Shell 中 。 任 何 在 输 出 变量 后 的 Shell 下 直 接 或 间 接 调 用 的 Shell 脚 本 程 序 都 会 得 到 输 出 变 量 初 始 值 的 一个 拷 贝 。
Shell 算 术 赋 值 操 作 : let 命 令
let 命 令 是 BASH Shell 下 对 数 字 型 变 量 进 行 操 作 的 操 作 算 子 。 通 过 该 命 令 , 你 可 以 比 较 两 个 值 或 者 执 行 算 术 操 作 如 加 法 、 乘 法 等 。 这 些 操 作 算 子 通 常 被 用在 Shell 程 序 中 , 以 管 理 控 制 结 构 或 执 行 必 要 的 计 算 。 let 命 令 用 关 键 词 let 来 标识 。 该 命 令 的 句 法 如 下 : 关 键 词 let 后 跟 着 两 个 数 字 , 而 数 字 之 间 由 一 个 算 术 或关 系 操 作 算 子 把 它 们 分 隔 开 。
$ let value1 operator value2
你 可 以 使 用 表 15-4 列 出 的 任 何 操 作 算 子 。 let 自 动 假 定 操 作 算 子 是 算 术 算 子或 关 系 算 子 。 你 不 必 象 在 Shell 用 变 量 求 值 符 “ $ ” 去 求 变 量 的 值 , 因 为 let 命令 会 自 动 求 出 变 量 的 值 , 并 把 它 们 的 值 转 换 成 数 字 。 这 也 意 味 着 你 可 以 在 你 的数 字 算 子 中 使 用 简 单 的 数 字 表 达 式 。 在 下 面 的 例 子 中 , let 命 令 把 2 和 7 相 乘 , 相 乘 后 的 结 果 输 出 到 标 准 输 出 。
$ let 2*7
14
如 果 你 想 在 算 术 表 达 式 的 操 作 数 之 间 输 入 空 格 , 你 必 须 用 双 引 号 把 整 个 算术 表 达 式 括 起 来 。 此 时 , let 表 达 式 如 下 :
$ let "2 * 7 "
你 也 可 以 在 let 表 达 式 中 包 含 赋 值 操 作 算 子 。 在 下 面 的 例 子 中 , 乘 法 的 计 算结 果 被 赋 值 给 变 量 res 。
$ let "res = 2 * 7 "
$ echo $res 14
$
你 也 可 以 在 数 字 之 间 使 用 任 何 关 系 操 作 算 子 来 进 行 比 较 操 作 , 例 如 , 可 以用 关 系 算 子 来 检 查 一 个 数 字 是 否 大 于 另 一 个 数 字 。 关 系 操 作 算 子 通 常 用 来 管 理控 制 结 构 , 例 如 循 环 控 制 结 构 或 条 件 控 制 结 构 。 在 下 面 的 例 子 中 , 脚 本 程 序helloprg 显 示 字 符 串 “ Hello ” 三 次 。 该 程 序 用 let 命 令 小 于 或 等 于 操 作 算 子 来管 理 控 制 循 环( let "again <= 3" ),并 用 let 命 令 使 变 量 again 逐 次 加 1( let "again
= again +1" ) 。 必 须 注 意 , 当 变 量 again 被 加 1 时 , 变 量 前 不 必 加 入 求 值 符 号“ $ ” , let 命 令 将 在 表 达 式 中 自 动 求 出 变 量 again 的 值 。
helloprg 脚 本 程 序 清 单 :
again=1
while let "again <= 3" do
echo $again Hello let "again = again +1 "
done
$ Helloprg 1 Hello
-
Hello
-
Hello
-
控 制 结 构
-
你 可 以 在 Shell 程 序 脚 本 中 使 用 Shell 控 制 结 构 来 控 制 Linux 命 令 的 执 行 。控 制 结 构 可 以 使 你 重 复 执 行 某 个 命 令 或 者 在 选 择 执 行 一 些 命 令 中 特 定 的 一 个 或几 个 命 令 。 控 制 结 构 主 要 由 两 部 分 组 成 : 测 试 条 件 命 令 与 要 执 行 的 命 令 。 如 果测 试 条 件 返 回 条 件 为 真 , 则 其 后 的 命 令 将 被 执 行 。 因 此 通 过 使 用 控 制 结 构 这 种方 式 , 你 可 以 在 可 能 将 要 执 行 的 命 令 之 间 作 出 选 择 。
主 要 有 两 类 不 同 的 控 制 结 构 : 循 环 控 制 结 构 及 条 件 控 制 结 构 。 循 环 控 制 结构 用 来 重 复 执 行 一 些 命 令 , 而 条 件 控 制 结 构 只 有 在 满 足 某 种 条 件 时 才 执 行 相 应的 命 令 。BASH Shell 有 三 种 主 要 的 循 环 控 制 结 构 : W hile 循 环 、for 循 环 及 for-in 循 环 ; 有 两 种 条 件 控 制 结 构 : if 条 件 控 制 结 构 及 case 条 件 控 制 结 构 。
while 及 if 控 制 结 构 是 更 常 见 的 控 制 结 构 , 用 它 们 可 以 实 现 多 种 功 能 , 如 执行 重 复 操 作 及 在 各 种 不 同 的 测 试 条 件 下 作 出 选 择 等 。 case 及 for 控 制 结 构 是 更专 门 化 的 控 制 结 构 。 case 控 制 结 构 是 if 条 件 控 制 结 构 的 一 种 受 限 形 式 , 它 常 用
来 实 现 菜 单 ; for 控 制 结 构 是 一 种 有 限 次 循 环 结 构 , 它 在 执 行 每 个 循 环 的 过 程 中会 把 列 表 中 一 系 列 的 赋 值 给 变 量 , 直 至 这 些 列 表 中 的 值 被 赋 值 完 毕 。
if 及 while 控 制 结 构 以 运 行 Linux 命 令 作 为 它 们 的 测 试 条 件 。 所 有 的 Linux 命 令 在 它 们 这 些 完 毕 后 都 会 返 回 一 个 退 出 状 态 ( exit status ) , 如 果 该 命 令 被 成功 执 行 , 那 么 , 该 命 令 返 回 的 退 出 状 态 为 0 , 如 果 该 命 令 由 于 某 种 原 因 运 行 失败 , 那 么 , 该 命 令 返 回 的 退 出 状 态 将 会 是 一 个 正 整 数 , 这 个 数 具 体 与 它 们 的 失败 原 因 有 关 。 if 及 while 控 制 结 构 将 检 查 执 行 的 Linux 命 令 的 返 回 值 , 看 这 一 返回 值 是 0 还 是 其 它 的 数 字 。 对 于 if 及 while 控 制 结 构 , 如 果 测 试 命 令 的 退 出 状态 是 0 , 这 测 试 条 件 命 令 被 成 功 执 行 , 然 后 开 始 执 行 控 制 结 构 中 的 命 令 。
测 试 命 令
通 常 , 你 可 能 需 执 行 一 个 比 较 测 试 操 作 , 通 过 该 操 作 来 比 较 两 个 值 的 大 小 , 而 在 控 制 结 构 中 使 用 的 测 试 操 作 是 一 个 Linux 命 令 , 不 是 一 个 关 系 表 达 式 。 但如 果 要 在 控 制 结 构 中 比 较 两 个 值 , 你 可 以 用 Linux 系 统 中 的 test 命 令 来 执 行 这一 比 较 操 作 。 test 命 令 将 比 较 两 个 值 , 并 返 回 该 命 令 的 退 出 状 态 , 如 果 该 命 令被 成 功 执 行 , 其 返 回 状 态 将 为 0 。
通 过 test 命 令 , 你 可 以 比 较 整 数 、 字 符 串 , 甚 至 执 行 一 个 逻 辑 操 作 。 该 命令 由 关 键 词 test 开 头 , 其 后 是 要 比 较 的 值 , 这 两 个 比 较 的 值 之 间 被 一 个 选 项 分隔 开 ( 该 选 项 用 来 指 定 要 进 行 比 较 的 类 别 ) 。 这 个 选 项 可 以 认 为 是 一 个 操 作 算子 , 只 是 在 输 入 该 选 项 的 时 候 用 一 个 负 号 “ -” 及 一 个 字 母 表 示 , 例 如 , -eq 选项 表 示 比 较 两 个 值 之 间 是 否 相 等 。 但 是 , 对 于 两 个 字 符 窜 比 较 操 作 实 际 上 是 一个 操 作 算 子 , 而 不 是 一 个 选 项 。 当 你 比 较 两 个 字 符 串 是 否 相 等 的 时 候 , 你 要 使
用 等 号 “ = ” , 对 于 不 等 号 , 用 “ != ” 表 示 。 表 15-5 中 列 出 了 test 命 令 中 使 用的 所 有 选 项 与 操 作 算 子 。 test 命 令 的 句 法 如 下 :
test value -option value test string = string
在 下 面 的 一 个 例 子 中 , 用 户 比 较 两 个 整 数 是 否 相 等 。 此 时 , 你 需 使 用 相 等选 项 -eq , 该 命 令 通 过 test 命 令 的 退 出 状 态 来 检 查 测 试 操 作 的 测 试 结 果 。 Shell 特 殊 变 量 “ $? ” 用 来 保 存 最 近 一 个 Linux 命 令 的 退 出 状 态 ( 返 回 值 ) 。
$ num=5
$ test $num -eq 10
$ echo $?
1
你 也 可 以 使 用 方 括 号 而 不 用 test 命 令 中 的 test 关 键 词 。 例 如 , 对 于 test 命令 test $greeting="hi" , 你 可 以 些 写 成 :
$ [ $greeting = "hi" ]
同 样 , test 命令 test $num -eq 10 也 可 以 写 成 :
$ [ $num -eq 10 ]
方 括 号 本 身 与 其 它 字 符 之 间 必 须 用 空 白 字 符 隔 开 , 这 些 空 白 字 符 可 以 是 空格 、 TAB 键 或 回 车 符 等 , 如 果 没 有 空 白 字 符 , 那 么 , 该 命 令 是 无 效 的 。
test 命 令 是 一 个 Linux 系 统 命 令 , 该 命 令 在 测 试 控 制 结 构 中 被 大 量 使 用 。 必须 注 意 , 该 命 令 对 字 符 串 及 整 数 等 类 型 有 不 同 的 选 项 。 同 时 , 不 要 混 淆 字 符 串比 较 与 整 数 比 较 选 项 之 间 的 区 别 , 对 于 比 较 两 个 字 符 串 是 否 相 等 , 用 选 项“ = ” ,
而 对 两 个 整 数 的 比 较 , 需 用 选 项 “ -eq ” 。
条 件 控 制 结 构 : if、 if-else 、 elif 及 case
BASH Shell 中 有 一 组 条 件 控 制 结 构 , 这 组 控 制 结 构 允 许 你 选 择 要 执 行 的 命令 。 这 些 控 制 结 构 基 本 上 与 其 它 程 序 设 计 语 言 中 的 条 件 控 制 结 构 基 本 相 同 , 但仍 然 有 一 些 差 别 。 if 条 件 控 制 结 构 用 来 测 试 一 个 Linux 命 令 的 执 行 后 的 退 出 状态 ( 返 回 值 ) , 而 不 是 一 个 表 达 式 。 此 外 , if-then 条 件 控 制 结 构 必 须 以 关 键 词 fi 结 尾 , 而 case 命 令 必 须 用 关 键 词 esac 结 尾 。 条 件 控 制 结 构 的 详 细 句 法 见 表15-6 。
if-then 条 件 控 制 结 构
if 条 件 控 制 结 构 用 来 在 命 令 执 行 之 前 设 置 一 个 条 件 选 项 , 该 条 件 选 项 是 一 个指 定 的 Linux 命 令 的 退 出 状 态 ( 返 回 值 ) 。 如 果 该 命 令 被 成 功 运 行 , 其 返 回 值将 为 0 , 然 后 , if 控 制 结 构 中 的 命 令 将 被 执 行 ; 如 果 该 命 令 的 返 回 值 为 一 个 任 何非 0 值 , 这 表 明 该 命 令 运 行 失 败 , 则 if 控 制 结 构 内 的 命 令 将 不 会 被 执 行 。
if 控 制 结 构 以 关 键 词 if 开 头 ,其 后 跟 一 个 Linux 命 令 ,该 命 令 的 退 出 状 态( 返回 值 ) 将 被 引 用 , 且 该 命 令 始 终 将 会 被 执 行 ; 该 命 令 之 后 是 另 起 一 行 的 关 键 词then , 再 其 后 可 以 是 任 何 一 组 Linux 命 令 。 最 后 , 由 关 键 词 fi 来 结 束 该 条 件 控制 结 构 。 通 常 你 需 根 据 一 个 Linux 命 令 是 否 成 功 执 行 来 在 两 组 可 能 的 命 令 之 间作 出 选 择 , 其 中 , else 关 键 词 正 是 用 来 使 if 控 制 结 构 在 这 两 个 可 能 的 选 项 之 间作 出 选 择 。 如 果 Linux 命 令 成 功 运 行 , 那 么 , 关 键 词 then 后 的 命 令 将 被 执 行 ; 反 之 , 如 果 该 命 令 运 行 失 败 , 那 么 , 关 键 词 else 命 令 之 后 的 命 令 将 被 执 行 。 if-
then-else 控 制 结 构 的 句 法 如 下 :
if Linux Command then
commands else commands fi
下 面 的 脚 本 例 子 程 序 elsels 用 来 执 行 带 不 同 选 项 的 列 文 件 命 令 -ls 命 令 , 这两 个 可 能 的 选 项 是 或 者 列 出 文 件 的 大 小 , 或 者 列 出 文 件 的 所 有 信 息 。
elsels 脚 本 程 序 清 单
echo Enter s to list file sizes,
echo otherwise all file information is listed. echo -n "Please enter option:"
read choice
if [ "$choice" = s ]
then ls -s
else ls -l fi
echo Good-bye
$ elsels
Enter s to list file sizes,
otherwise all file informaton is listed.
P lease enter option: s total 2
1 monday 2 today Good-bye
$
在 Shell 脚 本 程 序 中 , if 控 制 结 构 也 通 常 被 用 来 检 查 用 户 是 否 输 入 了 合 适 的参 数 数 。 特 殊 Shell 变量 “ # ” 将 保 存 用 户 输 入 的 参 数 数 量 。 在 测 试 命 令 中 使 用“ $# ” , 可 以 检 查 用 户 是 否 输 入 了 正 确 的 参 数 数 。
如 果 用 户 在 命 令 行 上 输 入 了 不 正 确 的 参 数 个 数 , 你 可 以 结 束 该 Shell 脚 本 程序 的 执 行 。 你 可 以 用 exit 命 令 来 结 束 Shell 脚 本 程 序 , 并 返 回 退 出 状 态 。 exit 命令 可 以 返 回 一 个 参 数 值 ,
例 如 , 返 回 值 为 0 表 明 该 脚 本 程 序 成 功 运 行 后 结 束 , 而 其 它 返 回 值 , 如 1 , 表 明 脚 本 程 序 运 行 时 发 生 了 错 误 。 在 下 面 的 例 子 中 , ifarg 脚 本 程 序 只 需 输 入 一个 参 数 。 如 果 用 户 在 输 入 参 数 的 过 程 中 少 输 入 了 一 个 命 令 行 参 数 , 或 者 用 户 多输 入 了 一 个 命 令 行 参 数 , if 条 件 控 制 结 构 将 为 真 , 错 误 的 消 息 将 被 打 印 出 , 脚本 程 序 也 将 退 出 , 并 返 回 一 个 表 示 程 序 运 行 出 错 的 一 个 返 回 值 。
ifarg 脚 本 程 序 清 单 :
if [ $# -ne 1 ]
then
echo Invalid number of arguments exit 1
fi
exho $1
$ ifarg
Invalid number of argumnets
elif 控 制 结 构 允 许 你 在 该 控 制 结 构 中 嵌 入 if-then-else 控 制 结 构 。 elif 结 构 表示 “ else if” , 该 控 制 结 构 可 以 使 你 在 几 个 可 能 的 选 项 之 间 作 出 选 择 。 第 一 个 选项 用 if 结 构 指 定 , 其 后 跟 另 一 个 可 能 选 项 , 每 个 可 能 选 项 都 由 其 自 己 的 elif 控制 结 构 指 定 。 最 后 一 个 elif 控 制 结 构 的 可 能 选 项 用 else 来 指 定 。 如 果 第 一 个 if 控 制 结 构 的 条 件 测 试 失 败 , 那 么 , 控 制 结 构 将 把 程 序 控 制 流 程 传 递 给 其 后 的 elif 控 制 结 构 , 如 果 又 失 败 , 那 么 , 程 序 控 制 流 程 将 传 递 给 下 一 个 elif 控 制 结 构 。该 过 程 直 至 到 满 足 条 件 的 测 试 命 令 , 然 后 , 该 elif 控 制 结 构 中 的 命 令 将 被 执 行 。最 后 , 程 序 的 控 制 流 程 传 递 给 以 fi 关 键 词 结 尾 的 if 控 制 结 构 之 外 。
逻 辑 命 令 : && 及 ||
逻 辑 命 令 用 来 对 两 个 Linux 命 令 执 行 逻 辑 操 作 。 该 命 令 的 句 法 如 下 :
command && command
command || command
对 于 逻 辑 与 “ && ” , 如 果 两 个 命 令 都 成 功 运 行 , 那 么 , 该 逻 辑 命 令 的 退 出状 态 ( 返 回 值 ) 为 0 。 对 于 逻 辑 或 “ ||” , 如 果 任 何 一 个 命 令 成 功 运 行 , 那 么 , 逻 辑 或 命 令 成 功 运 行 , 并 该 返 回 该 命 令 的 退 出 状 态 为 0 。 逻 辑 命 令 可 以 使 你 在控 制 结 构 的 测 试 命 令 中 使 用 逻 辑 操 作 。
case
case 控 制 结 构 可 以 使 你 在 几 个 可 能 的 选 项 之 间 作 出 选 择 。 它 通 过 一 个 字 符串 与 其 它 几 个 可 能 的 模 式 之 间 的 比 较 结 果 来 作 出 相 应 选 择 。 每 个 可 能 的 模 式 都与 一 组 操 作 相 关 联 。 如 果 找 到 与 字 符 串 匹 配 的 模 式 , 那 么 , 与 该 模 式 相 关 的 一组 操 作 将 被 执 行 。 case 控 制 结 构 以 关 键 词 case 开 始 , 其 后 跟 一 个 字 符 串 变 量 , 然 后 是 关 键 词 in , 再 其 后 是 一 组 可 能 的 模 式 ,每 个 模 式 可 以 是 一 个 正 则 表 达 式 , 并 以 回 括 符 结 束 。 在 回 括 符 之 后 是 列 出 的 与 该 模 式 想 关 联 的 一 组 命 令 , 再 在 一个 独 立 的 行 上 输 入 两 个 分 号 “ ;” , 表 明 与 该 模 式 关 联 的 一 组 命 令 已 经 结 束 。 最后 是 以 关 键 词 esac 结 尾 的 case 命 令 。 该 控 制 结 构 的 句 法 如 下 :
case string in pattern) commands
;;
pattern) commands
;;
*)
default commands
;;
esac
在 上 面 的 模 式 中 可 以 包 含 任 何 Shell 特殊字符。这些 Shell 特 殊 可 以 是“ * ”、“ [ ] ” 、 “ ? ” 及 “ |” 等 。 你 可 以 用 单 个 特 殊 字 符 “ * ” 来 指 定 一 个 缺 省 的 模式 。 该 特 殊 字 符 “ * ” 可 以 与 任 何 模 式 匹 配 , 因 此 , 它 可 以 作 为 一 个 非 常 有 用 的缺 省 项 。 如 果 字 符 串 与 所 有 的 模 式 都 不 匹 配 , 则 它 必 与 特 殊 字 符 “ * ” 匹 配 。 这样 , 如 果 没 有 与 指 定 的 字 符 串 匹 配 的 模 式 , 缺 省 项 将 被 执 行 。 缺 省 项 是 可 选 的 , 你 可 以 不 输 入 该 项 。
一 个 case 结 构 通 常 用 来 实 现 菜 单 。 在 下 面 的 脚 本 程 序 ischoice 中 , 程 序 问用 户 以 何 种 形 式 列 出 当 前 目 录 下 的 所 有 文 件 。 注 意 , 本 程 序 中 的 缺 省 项 用 来 警告 用 户 输 入 无 效 。
lschoice 脚 本 程 序 清 单 :
#Program to allow the user to select different ways of # listing files
echo s. List Sizes
echo l. List all File Information echo c. List C Files
echo -n "Please enter choice: " read choice
case $choice in
s) ls -s
;;
s) ls -l
;;
c) ls *.c
;;
*)
echo Invalid Option esac
$ lschoice
s. List Sizes
l. List all File Information
c. List C Files
P lease enter choice: c main.c lib.c file.c
$
循 环 控 制 结 构 : wh ile , for-in 及 for
BASH Shell 有 一 组 循 环 控 制 结 构 , 这 组 循 环 控 制 结 构 允 许 你 重 复 执 行 一 个
Linux 命 令 。这 些 循 环 控 制 命 令 是 :while 、for-in 及 for 控 制 结 构 。与 BASH Shell 中 的 if 控 制 结 构 一 样 , while 及 until 控 制 结 构 也 需 测 试 一 个 Linux 命 令 的 执 行结 果 。 但 是 , for 及 for-in 控 制 结 构 不 用 执 行 条 件 测 试 命 令 。 它 们 只 是 简 单 地 把列 表 中 的 一 系 列 值 依 次 赋 值 给 指 定 的 变 量 来 重 复 执 行 循 环 命 令 。 此 外 , while 及until 控 制 结 构 与 在 其 它 程 序 设 计 语 言 中 的 相 应 结 构 类 似 , 但 for 及 for-in 控 制 结构 却 有 很 大 的 不 同 。 循 环 控 制 结 构 的 用 法 见 表 15-6 。
Wh ile 循 环 控 制 结 构
while 循 环 控 制 结 构 用 来 重 复 执 行 命 令 。 while 循 环 控 制 结 构 以 关 键 词 while 开 头 , 其 后 是 一 个 Linux 命 令 , 然 后 下 一 行 是 do 关 键 词 。 该 结 构 用 关 键 词 done 表 示 循 环 控 制 的 结 束 。
下 面 是 whle 循 环 控 制 结 构 的 句 法 :
while Linux command do
commands done
while 控 制 结 构 中 的 Linux 命 令 通 常 是 一 个 用 方 括 号 括 起 来 的 测 试 命 令 。 在下 面 的 脚 本 程 序 myname 中 , 程 序 要 求 用 户 输 入 用 户 名 , 然 后 , 该 程 序 打 印 出用 户 的 名 字 。 该 循 环 控 制 结 构 通 过 用 test 命令 ( 以 用 方 括 号 括 起 来 的 方 式 ) 来测 试 变 量 的 值 。
myname 脚 本 程 序 清 单 :
again=yes
while [ "$again" = yes ]
do
echo -n "Please enter a name:" read name
echo "The name you entered is $name"
echo -n "Do you wish to continute ?" read again
done
echo Good-bye
$ myname
P lease enter a name: George The name you entered is George Do you wish to continute? yes
P lease enter a name: Robert The name you entered is Robert Do you wish to continute? no Good-bye
$
for-in 循 环 控 制 结 构
for-in 循 环 控 制 结 构 可 以 用 来 依 次 引 用 一 列 表 中 的 值 。 该 控 制 结 构 有 两 个 操
作 数 : 一 个 变 量 及 一 个 值 列 表 。 在 for-in 循 环 控 制 结 构 中 , 列 表 中 的 每 一 个 值被 依 次 赋 值 给 变 量 。 与 W hile 循 环 控 制 结 构 一 样 , for-in 控 制 结 构 也 是 一 种 循 环控 制 结 构 , 每 执 行 一 次 该 循 环 后 , 列 表 中 的 下 一 个 值 将 被 赋 值 给 变 量 。 当 到 达值 列 表 的 表 尾 后 , for-in 循 环 控 制 结 构 将 会 停 止 。 与 while 循 环 一 样 , for-in 控制 结 构 的 循 环 体 以 关 键 词 do 开 头 , 以 关 键 词 done 为 结 束 。
for-in 控 制 结 构 的 句 法 如 下 :
for variable in list-of-values do
commands done
在 下 面 的 脚 本 程 序 mylistfor 中 , 用 户 简 单 地 输 出 列 表 中 的 每 个 项 , 并 在 列表 项 后 加 上 当 天 的 日 期 。 该 列 表 中 的 每 个 项 被 依 次 赋 值 给 变 量 grocery。
mylistfor 脚 本 程 序 清 单 :
tdate='date+D'
for grocery in milk cookies apples cheese do
echo "$grocery $tdate" done
$ mylistfor
m ilk12/23/93 cookies 12/23/93 apples 12/23/93
cheese 12/23/93
$
for-in 循 环 控 制 结 构 在 管 理 文 件 时 非 常 方 便 。 你 可 以 使 用 特 殊 字 符 来 生 成 一个 文 件 名 列 表 , 然 后 在 for-in 循 环 控 制 结 构 中 使 用 这 个 文 件 名 列 表 。 例 如 , 特殊 字 符 “ * ” 将 列 出 当 前 目 录 下 的 所 有 文 件 , 而 “ *.c ” 将 列 出 当 前 目 录 下 所 有 扩展 名 为 .c 的 文 件 。 如 果 在 for-in 控 制 结 构 中 使 用 特 殊 字 符 “ * ” ( 见 下 例 ) 将 生成 由 你 当 前 目 录 下 的 所 有 文 件 名 组 成 的 列 表 。
for myfiles in * do commands done
下 面 的 脚 本 程 序 cbackup 用 来 把 当 前 目 录 下 的 所 有 扩 展 名 为 .c 的 文 件 拷 贝到 名 为 sourcebak
的 目 录 下 。 请 注 意 , 该 例 子 中 特 殊 字 符 “ * ” 的 使 用 。
cbackup 脚 本 程 序 清 单 :
for backfile in *.c do
cp $backfile sourcebak/$backfile
echo $backfile done
$ cbackup io.c
lib.c main.c
$
for 循 环 控 制 结 构
for 循 环 控 制 结 构 中 没 有 如 for-in 控 制 结 构 中 使 用 的 值 列 表 ( for-in 控 制 结
构 中 用 该 值 列 表 来 作 为 命 令 行 参 数 ) 。 对 于 for 循 环 控 制 结 构 , 它 把 运 行 脚本 程 序 时 输 入 的 命 令 行 参 数 作 为 其 循 环 值 列 表 , 而 for 命 令 将 自 动 依 次 把 这 些值 赋 值 给 for 循 环 中 的 变 量 。
在 执 行 第 一 次 循 环 时 , 命 令 行 的 第 一 个 参 数 将 被 赋 值 给 for 循 环 中 变 量 , 而在 执 行 第 二 次 循 环 时 , 命 令 行 的 第 二 个 参 数 将 被 赋 值 给 for 循 环 中 变 量 , 依 此类 推 。 for 循 环 控 制 结 构 没 有 指 定 值 列 表 , 但 你 必 须 在 执 行 脚 本 程 序 的 命 令 行 上输 入 必 要 的 参 数 去 指 定 列 表 中 的 项 。 “ $@ ” 是 一 个 特 殊 参 数 变 量 , 它 的 值 就 是命 令 行 上 的 所 有 参 数 组 成 的 一 个 列 表 。 看 下 面 的 例 子 : 当 运 行 例 子 脚 本 程 序cbackuparg 时 , 命 令 行 上 的 C 程 序 文 件 名 将 组 成 一 个 值 列 表 , 而 该 列 表 中 的每 个 文 件 名 将 被 自 动 依 次 赋 值 给 for 循 环 控 制 结 构 中 的 变 量 backfile 。 在 执 行 for 控 制 的 第 一 个 循 环 时 , 变 量 backfile 的 值 为 第 一 个 命 令 行 参 数 , 即 $1 , 而 在 执行 第 二 个 循 环 时 , 变 量 backfile 的 值 即 为 第 二 个 命 令 行 参 数 , 即 为 $2 。
cbackuparg 脚 本 程 序 清 单 :
for backfile do
cp $backfile source/$backfile echo "$backfile"
done
$ cbackuparg main.c lib.c io.c main.c
lib.c io.c
BASH Shell 小 结
Linux 系 统 下 开 发 出 了 三 种 不 同 的 Shell ,它 们 是 :BASH Shell 、PDKSH Shell 及 TCSH Shell 。 BASH Shell 同 时 具 有 PDKSH Shell 及 TCSH Shell 的 大 多 数高 级 特 性 , 包 括 命 令 行 编 辑 、 历 史 实 用 程 序 及 别 名 等 。 历 史 实 用 命 令 能 列 出 或查 询 你 先 前 所 执 行 的 命 令 , 你 甚 至 还 可 以 编 辑 并 运 行 这 些 编 辑 后 的 命 令 。 BASH Shell 下 的 alias 实 用 命 令 可 以 使 你 给 一 个 Linux 命 令 取 别 名 , 你 甚 至 还 可 以 给带 参 数 的 命 令 取 别 名 。
BASH Shell 下 还 有 一 组 Shell 特 征 开 关 变 量 。 三 个 常 见 的 特 征 开 关 变 量 是 :
ignoreeo f、 noclobber 及 noglob。 ignoreeof 开 关 变 量 可 以 防 止 你 意 外 的 退 出 ,
noclobber 开 关 变 量 可 以 防 止 你 在 使 用 重 定 向 时 意 外 地 覆 盖 已 经 存 在 的 文 件 , 而 noglob 开 关 变 量 可 以 把 Shell 特 殊 字 符 看 作 普 通 的 文 本 字 符 。
BASH Shell 下 也 有 一 组 特 殊 的 变 量 , 通 过 这 些 变 量 , 你 可 以 配 置 你 的 用 户Shell 。 在 这 些 特 殊 变 量 中 , 有 的 变 量 是 由 系 统 定 义 的 , 你 不 能 再 重 新 定 义 或 赋值 给 它 们 , 还 有 一 些 是 用 户 定 义 变 量 , 你 必 须 明 确 地 定 义 并 赋 值 给 它 们 。 通 过使 用 这 些 特 殊 变 量 , 你 可 以 配 置 你 的 用 户 环 境 。 例 如 , PATH 特 殊 变 量 用 来 指定 你 运 行 的 Linux 命 令 或 实 用 程 序 所 在 的 目 录 ; EXINI 变 量 用 来 保 存 编 辑 器 Ex 及 Vi 的 缺 省 配 置 。
有 一 些 特 殊 变 量 是 在 登 陆 初 始 化 文 件 中 定 义 与 赋 值 的 。 登 陆 初 始 化 文 件 是
一 个 Shell 脚 本 程 序 , 该 脚 本 程 序 在 Shell 被 创 建 时 自 动 执 行 。 在 BASH Shell 中 , 登 陆 初 始 化 文 件 是 .bash_profile 。在 C Shell 中 , 登 陆 初 始 化 文 件 是 .login 。在 BASH Shell 中 还 有 一 个 名 为 .bash_logout 的 文 件 , 该 文 件 在 你 退 出 Shell 时被 自 动 执 行 。 所 有 的 Shell 都 有 其 Shell 初 始 化 文 件 , 这 些 文 件 在 你 进 入 Shell 时 自 动 执 行 。 BASH Shell 下 的 Shell 初 始 化 文 件 是 .bashrc 。
BASH Shell 有 象 其 它 程 序 设 计 语 言 一 样 的 程 序 设 计 能 力 。 你 可 以 在 BASH Shell 脚 本 程 序 中 定 义 变 量 , 并 给 这 些 变 量 赋 值 。 你 也 可 以 交 互 式 地 给 一 个 变 量赋 值 。 BASH Shell 还 有 一 组 控 制 结 构 , 包 括 条 件 控 制 结 构 及 循 环 控 制 结 构 等 。与 其 它 程 序 设 计 语 言 一 样 , 你 可 以 在 Shell 脚 本 程 序 中 设 计 程 序 语 句 , 并 执 行该 脚 本 程 序 。
你 可 以 在 Shell 中 定 义 变 量 , 并 给 这 些 变 量 赋 值 。 你 可 以 在 变 量 的 前 面 键 入特 殊 字 符 “ $ ” 来 引 用 该 变 量 的 值 。 你 也 可 以 把 变 量 作 为 命 令 行 参 数 , 该 变 量 的值 可 以 是 目 录 路 径 , 甚 至 还 可 以 是 将 要 运 行 的 Linux 命 令 。
你 可 以 用 文 本 编 辑 器 来 创 建 包 含 Shell 命 令 及 变 量 定 义 的 文 件 , 这 些 文 件 就是 我 们 所 说 的 Shell 脚 本 程 序 。 一 个 脚 本 程 序 甚 至 还 可 以 有 参 数 变 量 , 这 些 参数 变 量 用 来 接 收 你 在 命 令 行 上 输 入 的 各 种 参 数 。 通 过 设 置 Shell 脚 本 程 序 的 可执 行 权 限 , 你 可 以 把 该 Shell 脚 本 程 序 看 作 是 另 一 个 新 的 Linux 命 令 。
echo 、read 命 令 及 Here 文 件 等 可 以 用 来 控 制 脚 本 程 序 的 输 入 与 输 出 。echo 命 令 用 来 输 出 数 据 至 标 准 输 出 , 而 read 命 令 可 以 使 你 以 交 互 式 方 式 读 取 输 入 数据 至 变 量 。 这 些 数 据 是 来 自 标 准 输 入 输 入 的 数 据 , 它 可 以 是 来 自 键 盘 的 输 入 数据 , 或 者 是 来 自 于 一 个 文 件 的 重 定 向 。 Here 文 件 使 你 直 接 输 入 文 本 数 据 至 脚 本程 序 。 Here 操 作 是 在 符 号 “ << ” 之 后 输 入 用 户 定 义 的 结 束 定 界 符 , 定 界 符 后 输入 的 文 本 将 被 赋 值 给 一 个 命 令 。
BASH Shell 脚 本 程 序 中 常 使 用 的 变 量 是 字 符 变 量 , 即 它 们 以 字 符 串 作 为 其变 量 值 。 除 了 等 号 之 外 , 字 符 变 量 再 没 有 其 它 操 作 算 子 , 如 果 你 想 对 变 量 执 行算 术 、 关 系 操 作 等 , 你 必 须 使 用 let 命 令 。 在 BASH Shell 中 , let 命 令 可 以 使 你象 使 用 数 字 变 量 一 样 使 用 定 义 的 变 量 , 例 如 , 你 可 以 执 行 加 、 减 、 乘 、 除 等 操作 。
BASH Shell 中 使 用 的 循 环 控 制 结 构 及 条 件 控 制 结 构 与 其 它 程 序 设 计 语 言 使用 的 控 制 结 构 类 似 。 BASH Shell 中 使 用 的 循 环 控 制 结 构 有 : while 、 for-in 及 for 循 环 。条 件 控 制 结 构 是 if 及 case 结 构 。while 循 环 与 其 它 程 序 设 计 语 言 中 的 while 循 环 类 似 , 该 循 环 将 永 远 执 行 , 直 至 该 控 制 结 构 中 的 测 试 条 件 是 假 为 止 。 但 是 , 在 BASH Shell 控 制 结 构 中 的 测 试 条 件 是 一 个 Linux 命 令 。 Linux 系 统 中 的 所 有命 令 执 行 后 都 会 返 回 一 个 退 出 状 态 ( 返 回 值 ) , 以 表 明 该 该 命 令 是 否 被 成 功 运行 。 如 果 一 个 Linux 命 令 的 退 出 状 态 是 0 , 则 表 明 该 命 令 被 成 功 运 行 ; 如 果 一
个 Linux 命 令 的 退 出 状 态 是 非 0 值 , 则 表 明 该 命 令 没 能 成 功 运 行 。 对 于 while 循 环 ,其 测 试 条 件 也 是 一 个 Linux 命 令 。如 果 该 Linux 命 令 成 功 运 行 ,那 么 ,while 循 环 将 继 续 ; 如 果 该 Linux 命 令 运 行 失 败 , 那 么 , while 循 环 将 结 束 。
BASH Shell 下 的 特 殊 命 令 test 可 以 用 来 实 现 与 其 它 程 序 设 计 语 言 中 类 似 的测 试 条 件 。 test 命 令 可 以 对 两 个 变 量 值 进 行 比 较 操 作 或 关 系 操 作 。 如 果 比 较 操作 的 结 果 为 真 , 那 么 , test 命 令 的 退 出 状 态 将 为 0 , 表 明 该 命 令 成 功 运 行 ; 如果 比 较 操 作 的 结 果 为 假 , 那 么 , test 命 令 的 退 出 状 态 将 为 非 0 值 , 表 明 该 命 令运 行 失 败 。 在 test 命 令 中 , 你 可 以 使 用 关 系 操 作 算 子 ( 即 比 较 两 个 操 作 数 ) 来控 制 一 个 循 环 结 构 。
if 条 件 控 制 结 构 根 据 一 个 测 试 条 件 的 运 行 结 果 来 决 定 是 否 运 行 该 控 制 结 构 内的 命 令 。与 while 控 制 结 构 一 样 ,这 个 测 试 条 件 也 是 一 个 Linux 命 令 。如 果 该 Linux 命 令 成 功 运 行 ,那 么 ,if 控 制 结 构 内 的 命 令 将 被 执 行 。if 条 件 控 制 结 构 也 使 用 test 命 令 来 实 现 类 似 于 程 序 设 计 语 言 中 条 件 结 构 。 test 命 令 可 以 对 两 个 变 量 执 行 关系 操 作 , 如 果 关 系 操 作 的 结 果 为 真 , 那 么 , if 控 制 结 构 将 继 续 执 行 其 后 的 命 令 。你 可 以 使 用 elif 及 else 结 构 在 if 控 制 结 构 中 嵌 入 多 个 条 件 控 制 。 与 if 结 构 一 样 , elif 控 制 结 构 内 有 它 自 己 的 Linux 测 试 命 令 。
case 条 件 控 制 结 构 类 似 于 一 个 受 限 的 if 结 构 , 它 把 一 个 变 量 的 值 与 多 个 可能 的 模 式 进 行 比 较 , 如 果 找 到 与 变 量 值 匹 配 的 字 符 串 , 与 该 匹 配 的 模 式 相 关 联的 一 组 命 令 将 被 执 行 。 case 条 件 控 制 结 构 非 常 适 合 实 现 菜 单 , 即 它 可 以 让 用 户在 多 个 可 能 的 菜 单 选 项 之 间 作 出 选 择 。
for-in 循 环 控 制 结 构 用 来 把 列 表 中 的 一 系 列 值 依 次 赋 值 给 一 个 指 定 的 变 量 。该 结 构 中 没 有 测 试 条 件 。 for-in 控 制 结 构 中 的 一 系 列 值 可 以 由 任 何 一 个 Linux 命
令 生 成 。 例 如 , ls 命 令 可 以 生 成 一 个 文 件 名 列 表 。 这 个 列 表 中 的 值 也 可 以 是 一组 指 定 的 单 词 , 该 列 表 中 的 每 个 单 词 都 将 会 被 依 次 赋 值 给 for-in 结 构 中 指 定 的变 量 。 该 循 环 将 一 直 进 行 下 去 , 直 至 列 表 中 的 所 有 项 都 赋 值 给 指 定 的 变 量 为 止 。对 于 for 循 环 控 制 结 构 , 脚 本 程 序 不 会 指 定 其 列 表 项 中 的 每 一 项 , 而 在 运 行 其脚 本 程 序 时 把 该 脚 本 程 序 的 命 令 行 参 数 作 为 其 列 表 项 。
表 15-1 命 令 行 编 辑 、 history 命 令 及 查 询 历 史 事 件命 令 行 编 辑 命 令 功 能
CTRL-b 或 左 光 标 键 左 移 一 个 字 符 ( 移 至 前 一 个 字 符 )
CTRL-f 或 右 光 标 键 右 移 一 个 字 符 ( 移 至 后 一 个 字 符 )
CTRL-a 移 至 行 首
CTRL-e 移 至 行 尾
ESC f 后 移 ( forward ) 一 个 单 词
ESC b 前 移 ( backward ) 一 个 单 词
DEL 删 除 光 标 所 在 的 字 符
BACKSPACE 或 CTRL-d |
CTRL-h |
删 除 光 标 前 的 字 符 删 除 光 标 后 的 字 符 |
---|---|---|
CTRL-k CTRL-n |
删 除 至 行 尾 或 向 下 光 标 键 移 至 历 史 事 件 列 表 中 当 前 事 件 的 下 |
|
CTRL-p |
一 历 史 事 件 或 上 光 标 键 移 至 历 史 事 件 列 表 中 当 前 事 件 的 前 一 |
|
历 史 事 件 |
ESC < 移 至 历 史 事 件 列 表 表 首
ESC > 移 至 历 史 事 件 列 表 表 尾
EASC TAB 历 史 事 件 名 自 动 匹 配 与 自 动 扩 展
fc event-reference 用 标 准 编 辑 器 编 辑 一 个 事 件 , 然 后 执 行 之 选 项 :
-l 列 出 最 近 的 历 史 事 件 , 与 history 命 令 相 同
-e 编 辑 event-reference , 即 启 动 一 个 指 定 的 编辑 器 去 编 辑 指 定 的 历 史 事 件
!event num 用 历 史 事 件 号 来 查 询 一 个 历 史 事 件
!characters 用 历 史 事 件 的 字 符 前 缀 来 查 询 历 史 事 件
!?pattern? 用 模 式 来 查 询 历 史 事 件 列 表 中 的 事 件
!-event num 通 过 偏 移 量 ( 相 对 于 事 件 表 中 的 第 一 个 事 件 ) 来查 询 历 史 事 件
!num1-num2 引 用 历 史 事 件 号 在 num1 与 num2 之 间 的 事 件
表 15-2BASH Shell 特 殊 变 量 与 Shell 特 征 开 关 变 量
Shell 特 殊 变 量 功 能系 统 定 义 变 量
HOME 用 户 的 主 路 径 名
LOGNAME 用 户 登 陆 名
USER 用 户 登 陆 名
TZ 系 统 使 用 的 时 区
可 重 定 义 变 量
SHELL 用 户 正 在 使 用 的 Shell 类 别 及 其 应 用 程 序 所 在 路径
PATH 在 执 行 命 令 时 系 统 要 搜 索 的 目 录 路 径 列 表
PS1 主 Shell 命 令 提 示 符
PS2 次 选 Shell 命 令 提 示 符
IFS 定 界 符
MAIL 在 接 收 电 子 邮 件 时 mail 实 用 程 序 需 要 检 查 保 存 邮件 的 文 件 名
MAILCHECK 检 查 是 否 收 到 新 邮 件 的 时 间 间 隔用 户 定 义 特 殊 变 量
MAILPATH 在 接 收 电 子 邮 件 时 mail 实 用 程 序 需 要 检 查 的 邮 件文 件 路 径 名 列 表
TERM 终 端 名
CDPATH 执 行 cd 命 令 时 要 搜 索 的 子 目 录 路 径 名
EXINITEx/Vi 编 辑 器 的 初 始 化 命 令
BASH Shell 特 性 开 关 变 量
set -+o feature 可 以 用 set 命 令 来 设 置 BASH Shell 特 性 开 关 变
量 , -o 选 项 打 开 开 关 变 量 , 而 +o 选 项 关 闭 开 关 变量
$ set -o noclobber 打 开 开 关 变 量 noclobber
$ set +o noclobber 关 闭 开 关 变 量 noclobber
ingoreeof 禁 止 使 用 CTRL-D 退 出
noclobber noglob |
重 定 向 操 作 时 不 覆 盖 已 存 在 文 件 禁 止 文 件 名 中 特 殊 字 符 扩 展( 如 * 、? 、~ 、及[]) |
|
---|---|---|
表 |
15-3 BASH Shell 命 令 与 参 数 |
|
BASH Shell 命 令 |
功 能 |
|
break |
从 fo r、 while 及 loop 循 环 中 退 出 |
|
Continue |
跳 过 循 环 中 余 下 的 命 令 , 并 继 续 下 一 次 循 环 |
|
Echo |
显 示 变 量 值 |
|
-n 选 项 排 除 输 出 时 的 换 行 符 |
||
Eval |
执 行 命 令 行 |
|
Exec |
在 当 前 进 程 中 执 行 命 令 , 运 行 时 不 创 建 新 的 子 |
|
Exit |
Shell 而 使 用 当 前 的 Shell 从 当 前 Shell 中 退 出 |
|
export var |
在 每 个 子 Shell 中 生 成 变 量 var 的 一 个 拷 贝 ( 值 |
|
引 用 ) |
||
History |
列 出 历 史 事 件 列 表 中 的 事 件 |
|
let "expression" |
用 表 15-4 中 的 操 作 算 子 给 数 字 、 关 系 表 达 式 赋 值 |
|
( 表 达 式 必 须 用 双 引 号 括 起 来 ) |
||
Read Return |
从 标 准 输 入 上 读 取 一 行从 函 数 中 退 出 |
|
Set |
当 在 命 令 行 上 执 行 且 带 参 数 时 , 表 示 给 变 量 赋 新 |
|
的 值 , 当 不 带 任 何 参 数 时 , 表 示 将 列 出 当 前 定 义 |
的 所 有 变 量
Shift 把 所 有 的 命 令 行 参 数 左 移 , 于 是 引 用 该 参 数 时 的参 数 号 将 比 先 前 小 1 , 也 就 是 参 数 $3 将 赋 值 给 参数 $2 , 依 次 类 推 。 先 前 的 参 数 $1 将 丢 失
test value option value
[ value option value ]
比 较 两 个 参 数 , 用 在 Linux 命 令 的 控 制 结 构 中 test
2 -eq $coun t[ 2 -eq $coun t]
unset 取 消 一 个 变 量 的 定 义命 令 行 参 数
$0 Linux 命 令 名
$n 从 1 开 始 的 第 n 个 命 令 行 参 数 , 你 可 以 用 set 命令 去 改 变 它 们 的 值
$* 从 1 开 始 的 所 有 命 令 行 参 数 , 比 可 以 用 set 命 令去 改 变 它 们 的 值
$@ 可 以 被 逐 个 单 独 引 用 的 命 令 行 参 数
$# 命 令 行 参 数 的 个 数
$$ 当 前 进 程 的 进 程 ID 号 及 PID 号
$! 当 前 后 台 进 程 的 PID 号
$? 最 后 执 行 的 一 个 Linux 命 令 的 退 出 状 态 ( exit
status ) , 即 返 回 结 果
表 |
15-4 let 表 达 式 操 作 算 子 |
|
---|---|---|
算 术 操 作 算 子 |
功 能 |
|
+ |
加 |
|
- |
减 |
|
* |
乘 |
|
/ |
除 |
|
% |
取 模 - 除 法 的 余 数 |
|
关 子 操 作 算 子 |
||
> < |
大 于小 于 |
|
>= |
大 于 等 于 |
|
<= |
小 于 等 于 |
|
!= |
不 等 于 |
|
== |
等 于 |
|
& |
逻 辑 与 |
|
| ! |
逻 辑 或逻 辑 非 |
|
表 | 15-5 Test 命 令 操 作 选 项 | |
整 数 比 较 |
功 能 |
|
-gt |
大 于 |
|
-lt |
小 于 |
-ge 大 于 等 于
-le 小 于 等 于
-eq 等 于
-ne 不 等 于
字 符 串 比 较 功 能
-z 测 试 空 窜
-n 测 试 字 符 串 的 值
= 字 符 串 相 等
!= 字 符 串 不 等
str 测 试 一 个 字 符 串 是 否 不 是 空 窜
逻 辑 操 作 算 子 功 能
-a 逻 辑 与
-o 逻 辑 或
! 逻 辑 非 文 件 测 试 操 作 算 子 功 能
-f 文 件 存 在 , 且 是 一 常 规 文 件
-s 文 件 非 空
-r 文 件 是 可 读 文 件
-w 文 件 可 以 被 修 改 ( 写 入 )
-x 文 件 可 以 被 执 行
-d 文 件 是 一 个 目 录 名
-h 文 件 是 符 号 链
-c 文 件 与 一 特 定 设 备 关 联
-b 文 件 与 一 块 文 件 关 联
表 15-6BASH Shell 控 制 结 构 与 循 环
if, else,elif,case 功 能
if ( command ) then commands fi 如 果 其 测 试 命 令 被 成 功 运 行 , 那 么 , if
控 制 结 构 将 执 行 then 后 的 一 个 或 一组 命 令
if ( command ) then commands esle commands fi
if ( command ) then command
elif ( comamnd ) then command
else command
fi
case string in pattern)
command;;
esac
如 果 其 测 试 命 令 被 成 功 运 行 , 那 么 , if-else 控 制 结 构 将 执 行 then 后 的 一个 或 一 组 命 令 , 否 则 , else 后 的 一 个或 一 组 命 令 将 被 执 行
elif 可 以 允 许 你 在 该 控 制 结 构 中 嵌 入一 个 if 控 制 结 构 , 从 而 可 以 使 你 在 几个 可 能 选 项 之 间 进 行 选 择 , 如 果 if 后的 测 试 命 令 的 返 回 结 果 为 真 , 其 后 的命 令 将 被 执 行 , 而 控 制 结 构 将 退 出 整个 elif 控 制 结 构
case 控 制 结 构 中 的 string 与 多 个 可能 的 模 式 进 行 匹 配 , 如 果 找 到 匹 配 的模 式 , 那 么 , 与 该 匹 配 模 式 相 关 联 的命 令 将 被 执 行
command && command 如 果 两 个 命 令 的 返 回 值 都 是 0 , 那 么 ,
逻 辑 与 的 返 回 结 果 将 为 0 ; 如 果 其 中的 一 个 命 令 的 返 回 结 果 为 非 0 值 , 则逻 辑 与 的 返 回 结 果 为 非 0 , 逻 辑 与 的返 回 值 为 假
command || command 如 果 两 命 令 中 的 一 个 命 令 返 回 值 为0 , 那 么 , 逻 辑 OR 条 件 命 令 返 回 的结 果 将 为 0 , 逻 辑 或 将 返 回 0 ; 如 果两 个 命 令 都 返 回 值 一 个 非 0 值 , 那么 , 逻 辑 或 条 件 命 令 的 返 回 值 将 为假 , 并 返 回 一 个 非 0 值 !command 逻辑 非 将 反 置 命 令 的 返 回 值
循 环 控 制 结 构 : 功 能
while , until, for, for-in select while (command)
do command done
until command do
command done
for variable in list-values
do command
只 有 当 while 控 制 结 构 的 测 试 命 令 为真 时 , do 后 面 的 命 令 才 被 执 行
只 有 当 until 控 制 结 构 的 测 试 命 令 为假 时 , do 后 面 的 命 令 才 被 执 行
for-in 控 制 结 构 用 来 引 用 列 表 中 的 一系 列 值 , 列 表 中 的 值 被 逐 个 赋 值 给 变
done 量 variable
for variable do command done
select string in item-list do
command
done
for 循 环 控 制 结 构 用 来 引 用 执 行 脚 本程 序 时 输 入 的 命 令 行 参 数 。 命 令 行 参数 上 的 每 个 参 数 将 被 逐 个 赋 值 给 变 量variable
select 控 制 结 构 可 以 根 据 item-list 中的 项 创 建 一 个 菜 单 , 然 后 , 执 行 相 应的 命 令 , 该 命 令 通 常 是 一 个 case 控制 结 构