第 16 章 TCSH Shell

TCSH Shell 实 质 上 是 C-Shell 的 另 一 版 本 , 它 在 C-Shell 的 基 础 上 增 加 了许 多 新 的 特 性 。 它 与 标 准 的 C-Shell 完 全 兼 容 , 并 且 具 有 C-Shell 的 所 有 功 能 与特 性 ,包括 Shell 程 序 语 言 及 history 实 用 程 序 等 。C-Shell 本 身 最 初 是 为 BSD Unix 系 统 开 发 的 ,它 包 括 了 其 最 初 版 BourneShell 的 所 有 核 心 命 令 ,但 与 Bourne Shell 又 有 很 大 的 不 同 ,特 别 是 前 者 具 有 更 多 更 复 杂 的 特 性 ,如 Shell 程 序 设 计 。C-Shell 是 在 Bourne Shell 之 后 才 开 发 出 来 的 , 因 此 , 它 最 先 引 入 了 一 些 新 的 特 性 , 如命 令 行 编 辑 、 history 应 用 程 序 及 别 名 等 。 后 来 的 Korn Shell 具 有 上 述 这 些 特 性外 , 还 增 加 了 更 多 更 实 用 的 命 令 行 和 history 通 用 编 辑 命 令 。 同 样 , 这 些 功 能 也增 加 到 BASH 及 TCSH Shell 中 去 了 。 因 此 , 在 TCSH Shell 中 , 你 会 发 现 它比 最 初 的 C-Shell 具 有 更 多 的 高 级 命 令 行 与 history 编 辑 特 性 。

在 第 5 章 中 讨 论 过 , TCSH Shell 、 BASH Shell 及 PDKSH Shell 都 具 有 一些 基 本 的 Shell 命 令 。 TCSH Shell 与 其 它 Shell 的 一 个 显 著 不 同 是 它 以 “ > ” 符号 作 为 缺 省 的 命 令 提 示 符 , 而 不 是 “ $ ” 。 本 章 将 重 点 讨 论 TCSH Shell 与 其 它Shell 的 不 同 之 处 。具 体 地 说 ,主 要 是 讨 论 命 令 行 编 辑 、history 实 用 程 序 及 Shell 环 境 变 量 与 系 统 初 始 化 文 件 等 。 本 章 还 将 介 绍 TCSH Shell 下 的 Shell 编 程 。 表16-1 中 列 出 了 TCSH Shell 下 history 命 令 的 使 用 说 明 。

命 令 行 扩 展

命 令 行 有 一 个 内 在 特 征 , 那 就 是 命 令 行 与 文 件 名 扩 展 特 性 。 如 果 你 把 一 个输 入 还 没 有 完 成 的 字 符 串 作 为 一 个 文 件 名 参 数 , 你 可 以 键 入 TAB 键 来 激 活 这 一特 性 , 该 特 性 可 以 完 成 文 件 名 自 动 扩 展 。 如 果 你 键 入 CTRL-D , 那 么 , 系 统 将列 出 所 有 与 你 键 入 的 字 符 或 字 符 串 相 匹 配 的 文 件 名 。 你 可 以 在 命 令 行 上 键 入 文件 名 的 部 分 字 符 , 然 后 键 入 TAB 键 就 可 以 利 用 该 特 性 了 。 这 时 , Shell 将 寻 找与 你 所 键 入 的 部 分 前 缀 相 匹 配 的 文 件 名 , 并 自 动 将 文 件 名 扩 展 在 命 令 行 上 。

在 下 面 的 例 子 中 ,用 户 键 入 cat 命 令 ,并 在 其 后 键 入 一 个 还 未 完 成 的 文 件 名 , 当 用 户 键 入 TAB 键 后 , Shell 搜 索 与 之 相 匹 配 的 文 件 名 , 如 果 找 到 , 将 扩 展 该文 件 名 至 命 令 行 上 。

  • cat pre TAB

    • cat preface

如 果 不 止 一 个 文 件 具 有 与 你 键 入 的 前 缀 相 匹 配 , 系 统 将 尽 可 能 多 的 扩 展 与文 件 相 匹 配 的 字 符 , 然 后 响 铃 , 等 待 用 户 键 入 更 多 的 字 符 , 以 便 选 定 一 个 文 件 , 例 如 :

  • ls

document docudrama

  • cat doc TAB

    • cat docu beep

如 果 你 想 列 出 所 有 与 你 未 完 成 的 文 件 名 相 匹 配 的 文 件 , 可 以 在 命 令 行 上 键入 CTRL-D 。 下 面 的 例 子 中 , 在 没 完 成 的 文 件 名 后 键 入 了 CTRL-D , Shell 列 出了 所 有 用 户 可 能 想 输 入 的 文 件 名 。

  • cat doc CTRL-D document docudrama

  • cat docu

系 统 又 重 新 回 显 命 令 行 , 你 可 以 键 入 你 所 想 键 入 的 文 件 名 的 剩 下 部 分 , 或继 续 输 入 字 符 , 再 键 入 TAB 键 来 完 成 文 件 名 的 自 动 扩 展 。

  • cat docudrama

    1. history 命 令

和 BASH Shell 及 PDKSH Shell 一 样 , TCSH Shell 的 history 实 用 命 令 保存 最 近 你 所 执 行 的 一 些 命 令 。 history 实 用 命 令 用 一 小 段 内 存 来 记 录 有 限 个 最 近你 所 执 行 的 命 令 。 如 果 历 史 实 用 命 令 没 有 自 动 启 动 , 你 首 先 必 须 用 set 命 令 定义 它 , 并 赋 一 t 值 给 它 , 用 来 确 定 你 想 保 存 最 近 执 行 的 命 令 个 数 。 该 步 骤 通 常是 在 你 的 系 统 配 置 文 件 中 完 成 的 , 这 在 本 书 第 14 章 中 已 经 讨 论 过 。 下 面 的 例 子中 , 设 置 history 实 用 程 序 保 存 最 近 的 5 个 命 令 。

  • set history=5

这 些 被 保 存 的 命 令 在 Linux 系 统 中 通 常 被 称 为 事 件 ( even t) 。 要 想 查 看 最近 你 执 行 的 一 些 命 令 , 在 命 令 行 上 键 入 history 命 令 , 然 后 键 入 ENTER 键 ( 回车 键 ) , 那 么 , 你 最 近 执 行 的 一 些 命 令 的 列 表 将 回 在 屏 幕 上 ( 命 令 前 的 数 字 为历 史 记 录 号 ) 。

  • history 1 ls
  1. vi m ydata

  2. mv mydata reports

  3. cd reports 5 ls -F

>

history 实 用 命 令 能 让 你 查 询 以 前 的 历 史 事 件 , 并 可 把 它 们 显 示 到 命 令 行 上或 执 行 它 。 但 是 , 你 不 必 先 用 history 将 它 们 列 出 。 最 简 便 的 办 法 是 通 过 上 下 光标 键 , 把 先 前 的 一 个 个 事 件 逐 次 显 示 到 命 令 行 。 按 一 下 上 光 标 键 , 你 上 一 次 执行 的 一 个 事 件 将 出 现 在 命 令 行 上 。 再 按 一 下 , 上 一 次 的 前 一 事 件 又 会 出 现 在 命令 行 上 。 按 一 下 下 光 标 键 , 将 会 使 当 前 事 件 的 下 一 事 件 出 现 在 光 标 行 上 。

你 也 可 以 对 显 示 在 命 令 行 上 的 事 件 进 行 编 辑 。 通 过 左 右 光 标 键 在 命 令 行 上移 动 光 标 。 你 可 以 在 任 何 你 想 输 入 字 符 的 地 方 插 入 字 符 , 用 BASKSPACE 键 或DEL 键 删 除 你 想 要 删 除 的 字 符 , 用 CTRL-A 命 令 将 光 标 移 动 至 命 令 行 的 行 首 , 用 CTRL-E 命 令 将 光 标 移 动 至 命 令 行 行 尾 , 用 CTRL-K 命 令 删 除 光 标 后 所 有 的字 符 , 用 CTRL-U 命 令 删 除 整 行 。

显 示 的 历 史 事 件 列 表 是 用 户 在 对 历 史 事 件 进 行 搜 索 时 强 有 力 的 手 段 。 所 有这 些 历 史 事 件 可 以 通 过 历 史 事 件 的 事 件 号 、 事 件 的 初 始 字 符 或 字 符 串 及 字 符 匹配 等 方 式 查 询 到 。 一 种 查 询 方 式 是 在 字 符 串 中 嵌 入 “ ? ” 号 。 你 可 以 用 history 应 用 程 序 的 “ !” 号 命 令 重 新 执 行 历 史 事 件 。 在 “ ! ” 号 命 令 后 键 入 能 够 确 定 先前 事 件 的 关 联 字 符 , 这 关 联 字 符 可 以 是 先 前 事 件 的 历 史 事 件 号 , 或 者 该 事 件 的前 几 个 字 符 串 。 在 下 面 的 例 子 中 , 历 史 事 件 列 表 中 的 第 二 个 事 件 ( 历 史 事 件 号为 2 ) 的 事 件 被 查 询 到 。 同 时 , 又 用 其 开 头 几 个 字 符 串 去 匹 配 , 也 被 查 询 到 , 最 后 用 事 件 正 文 字 符 匹 配 方 式 也 被 查 询 到 。

  • !2

vi m ydata

  • !vi

vi m ydata

  • !?myd? vi m ydata

你 也 可 以 用 一 个 偏 移 量 ( 相 对 于 历 史 事 件 列 表 中 最 后 一 个 事 件 ) 来 查 询 历史 事 件 。 负 的 偏 移 量 将 通 从 历 史 事 件 列 表 表 尾 向 前 偏 移 , 从 而 查 询 到 所 要 的 事件 。 在 下 面 的 例 子 中 , 历 史 事 件 号 为 2 的 事 件 “ vi mydata ” 就 是 用 一 个 负 的 偏移 量 查 询 到 的 。

  • !-4

vi m ydata

惊 叹 号 “ !” 也 可 以 查 询 用 户 所 执 行 的 最 后 一 个 命 令 , 它 相 当 于 偏 移 量 为 -1 。在 下 面 的 例 子 中 , 惊 叹 号 “ !” 及 偏 移 量 为 -1 都 能 查 询 到 用 户 最 后 执 行 的 命 令 : ls -F 。

  • !!

ls -F

mydata /reports

  • !-1

ls -F

mydata /reports

16.2.1 历 史 事 件 替 换

一 个 事 件 关 联 ( 用 来 指 定 某 事 件 ) 可 以 认 为 它 代 表 了 组 成 该 事 件 的 字 符 串 。例 如 , “ !1 ” 实 际 上 代 表 字 符 串 “ ls ” 。 因 此 , 你 可 以 把 一 个 事 件 关 联 作 为 另 一个 命 令 的 一 部 分 。 历 史 事 件 的 运 行 基 本 上 就 是 一 个 替 换 操 作 , 即 用 组 成 历 史 事件 的 字 符 去 代 替 “ !” 号 及 其 事 件 关 联 。

在 下 面 的 例 子 中 , 首 先 列 出 历 史 事 件 列 表 , 然 后 , 第 一 个 历 史 事 件 的 关 联被 替 换 , 作 为 了 新 命 令 的 一 部 分 , 即 : “ !” 号 与 事 件 关 联 ( 此 处 为 历 史 事 件 号1 ) 被 替 换 成 “ ls ” , 成 为 命 令 : ls > myfiles 的 一 部 分 。

  • history 1 ls
  1. vi m ydata

  2. mv mydata reports

  3. cd reports 5 ls -F

  • !1 > myfiles ls > myfiles

你 也 可 以 引 用 某 历 史 事 件 中 特 定 的 单 词 。 一 个 事 件 可 被 分 解 为 几 个 单 词 , 我 们 可 以 从 0 开 始 依 次 给 每 个 单 词 编 号 。 在 一 个 事 件 关 联 后 键 入 “ : ” 号 , 然后 键 入 历 史 事 件 中 单 词 的 编 号 就 可 唯 一 确 定 一 个 单 词 。 例 如 , “ !3 ” 代 表 历 史事 件 号 为 3 的 事 件 mv mydata reports ,在 该 事 件 中 , 其 第 二 个 单 词 为 mydata , 因 此 , “ !3:1 ” 就 代 表 单 词 mydata 。 下 面 的 例 子 中 , “ 2:0 ” 代 表 事 件 2 中 编号 为 0 的 单 词 v i, 于 是 , 该 命 令 就 是 : vi preface 。

  • !2:0 preface

vi preface

用 一 系 列 的 数 字 , 你 可 以 从 一 个 事 件 中 引 用 几 个 单 词 。 在 第 一 个 单 词 与 最后 一 个 单 词 的 编 号 之 间 用 “ - ” 分 开 。 下 面 的 例 子 中 , 3:0-1 将 引 用 历 史 事 件 号为 3 的 事 件 中 前 两 个 单 词 m v 和 mydata 。

  • !3:0-1 oldletters mv mydata oldletters

特 殊 字 符 “ ^ ” 和 “ $ ” 分 别 代 表 一 个 事 件 中 第 二 个 单 词 及 最 后 一 个 单 词 ,

它 们 用 来 引 用 事 件 中 的 参 数 。 如 果 你 只 想 引 用 某 事 件 的 第 一 个 参 数 , 符 号 “ ^ ” 将 代 表 该 参 数 , 而 符 号 “ $ ” 代 表 该 事 件 的 最 后 一 个 参 数 。 “ ^-$ ” 将 引 用 事 件中 所 有 的 参 数 ( 只 有 事 件 的 第 一 个 单 词 即 命 令 名 将 不 被 引 用 ) 。 下 面 的 例 子 中 , 前 一 历 史 事 件 的 参 数 将 被 引 用 为 当 前 事 件 的 参 数 。 首 先 , 历 史 事 件 号 为 2 的 事件 的 第 一 个 参 数 ( 第 二 个 单 词 ) mydata 被 作 为 lpr 命 令 的 参 数 , 用 来 打 印 该 文件 ; 随 后 , 历 史 事 件 号 为 3 的 事 件 的 最 后 一 个 参 数 reports 被 作 为 ls 命 令 的 参数 , 用 来 列 出 reports 目 录 中 的 所 有 文 件 名 ; 最 后 , 历 史 事 件 号 为 3 的 事 件 的所 有 参 数 mydata 、 reports 被 用 来 作 cp 命 令 的 参 数 。

  • lpr !2:^ lpr mydata

>ls !3:$ ls reports

  • cp !3:^-$

cp mydata reports

符 号“ * ”也 是 一 个 特 殊 的 符 号 ,用 来 代 表 历 史 事 件 中 的 所 有 参 数 ,它 与“ ^-$ ” 的 功 能 是 相 同 的 。 上 例 中 最 后 一 个 例 子 可 以 符 号 “ * ” 代 替 如 下 :

  • cp !3:*

cp mydata reports

C -Shell 及 TCSH Shell 中 , 在 命 令 的 任 何 地 方 都 可 以 使 用 惊 叹 号 “ !” , 它会 被 解 释 为 对 历 史 事 件 的 引 用 。 如 果 由 于 某 些 原 因 , 你 要 使 用 惊 叹 号 “ !” , 例如 在 电 子 邮 件 地 址 中 , 必 须 用 在 惊 叹 号 前

放 置 反 斜 杠 “ \ ” 来 防 止 惊 叹 号 引 用 历 史 事 件 。

  • mail garne t\ !chris < m ydata

    1. 别 名

通 过 alias 命 令 , 你 可 以 给 一 个 命 令 创 建 一 个 新 的 名 字 。 alias 命 令 象 一 个宏 , 对 其 代 表 的 命 令 进 行 替 换 。 它 不 是 逐 字 对 命 令 名 进 行 替 换 , 而 是 仅 仅 对 命令 取 另 外 一 个 名 字 。 alias 命 令 由 关 键 词 alias 开 头 , 然 后 是 要 替 换 命 令 的 新 的名 字 , 其 后 是 空 格 及 将 要 替 换 的 命 令 。 下 面 的 例 子 中 , list 就 是 ls 命 令 的 一 个别 名 。

  • alias list ls

  • ls

mydata intro

  • list mydata intro

>

如 果 你 要 改 名 的 命 令 有 选 择 项 , 那 么 , 你 必 须 用 单 引 号 把 该 命 令 及 其 选 择

项 括 起 来 。 如 果 改 名 后 的 命 令 有 空 格 , 在 改 名 时 , 你 同 样 必 须 用 单 引 号 括 起 来 。下 面 的 例 子 中 , 带 -l 选 项 的 ls 命 令 被 改 名 为 long1 :

  • alias long1 'ls -l' ls -l

-rw-r--r-- 1 chris weather 207 Feb 20 11:55 mydata

  • long1

-rw-r--r-- 1 chris weather 207 Feb 20 11:55 mydata

>

你 也 可 以 用 一 个 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 命 令 取 消 别 名 lss 。

  • alias lss ls -s list ls rm rm -i

  • unalias lss

    1. TCSH Shell 特 征 变 量 : Shell 特 性

TCSH Shell 有 几 个 特 征 变 量 , 这 些 特 征 变 量 可 以 控 制 Shell 在 不 同 的 方 式下 工 作 。TCSH Shell 特 征 变 量 包 括 PDKSH Shell 中 定 义 的 一 些 变 量 以 及 TCSH Shell 中 专 有 的 一 些 变 量 。 例 如 在 TCSH Shell 中 有 一 开 关 变 量 noclobber, 可以 防 止 你 重 定 向 时 意 外 地 覆 盖 一 个 已 经 存 在 的 文 件 。 另 外 一 些 常 见 的 特 征 变 量有 : echo 、 noclobbe r、 ignoreeof 及 noglob 等 ( 见 表 16-2 ) 。

通 过 定 义 或 不 定 义 这 些 变 量 能 关 闭 或 打 开 与 该 特 征 变 量 相 关 的 TCSH Shell 特性 。 每 个 变 量 都 是 对 应 于 某 特 定 特 性 。 例 如 : 通 过 定 义 noclobber 特 征 变 量 , 能 打 开 noclobber 变 量 所 对 应 的 TCSH Shell 特 性 。 你 可 以 通 过 set 命 令 来 定 义一 个 特 性 变 量 , 用 unset 命 令 来 取 消 某 个 特 征 变 量 的 定 义 。 要 打 开 noclobber 变 量 所 对 应 的 特 性 , 你 可 以 键 入 命 令 : set noclobbe r, 要 关 闭 这 一 特 性 , 键 入命 令 : unset noclobbe r。

  • set feature-variable

  • unset feature-variable

通 常 这 些 特 征 变 量 也 被 称 为 按 钮 ( toggle ) 类 变 量 , 因 为 它 们 用 来 打 开 或 关闭 Shell 的 某 些 特 性 。

16.4.1echo

如 果 设 置 echo 特 征 变 量 , 将 使 TCSH Shell 具 有 如 下 特 性 : 在 每 次 执 行 一命 令 前 , TCSH Shell 将 首 先 显 示 该 命 令 。 set echo 命 令 将 打 开 上 述 特 性 , unset echo 将 关 闭 上 述 特 性 。

16.4.2ignoreeof

设 置 了 ignoreeof 变 量 后 , TCSH Shell 将 阻 止 用 户 使 用 CTRL-D 命 令 来 退出 用 户 Shell , 它 可 以 用 来 防 止 用 户 意 外 退 出 系 统 。 当 该 特 性 开 关 被 关 闭 时 , 你可 以 按 CTRL-D 键 来 退 出 系 统 。 但 是 , CTRL-D 不 仅 仅 被 用 来 退 出 Shell , 而 且可 以 用 来 终 止 用 户 直 接 输 往 标 准 输 出 上 的 输 入 。 该 操 作 经 常 在 ma il 程 序 和 一 些Shell 实 用 命 令 中 使 用 , 例 如 cat 实 用 命 令 。 你 可 能 在 上 述 实 用 程 序 操 作 中 , 非常 容 易 误 操 作 而 意 外 地 退 出 Shell 。 ignoreeof 特 殊 变 量 正 是 用 来 防 止 这 些 意 外的 退 出 。 当 该 变 量 被 设 置 时 , 你 只 能 用 logout 命 令 非 常 明 确 地 告 诉 Shell 你 想退 出 系 统 。

  • set ignoreeof

  • Ctrl- D

Use logout to logout

>

16.4.3noclobber

设 置 了 noclobber 变 量 后 , 可 以 使 在 重 定 向 输 出 时 保 护 已 存 在 的 文 件 。 如果 你 在 使 用 重 定 向 操 作 把 数 据 输 出 到 一 个 已 经 存 在 的 文 件 中 时 , 用 noclobber 这 一 特 殊 变 量 可 以 防 止 文 件 在 进 行 标 准 输 出 时 被 覆 盖 , 原 文 件 将 被 受 到 保 护 。这 种 情 况 有 可 能 发 生 在 把 重 定 向 输 出 的 内 容 保 存 到 你 输 入 的 文 件 名 中 , 而 你 给出 的 这 个 文 件 名 可 能 已 经 存 在 了 。 因 此 , noclobber 特 殊 变 量 可 以 防 止 你

意 外 地 覆 盖 一 个 已 经 存 在 的 原 文 件 。

  • set noclobber

  • cat preface > myfile myfile: file excists

>

你 可 能 觉 得 当 时 你 的 确 是 想 在 重 定 向 输 出 时 覆 盖 一 个 文 件 , 系 统 的 这 一 提示 将 浪 费 你 的 时 间 , 这 时 , 你 可 以 在 重 定 向 操 作 算 子 后 面 加 一 惊 叹 号 ( !) 。 这时 , 系 统 将 不 考 虑 noclobber 变 量 的 有 效 性 而 直 接 把 重 定 向 输 出 的 内 容 输 出 至指 定 的 文 件 。

  • cat preface >! myfile

16.4.4noglob

设 置 了 noglob 变 量 后 , Shell 将 不 扩 展 文 件 名 中 一 些 特 殊 的 字 符 或 字 符 串 。例 如 : 字 符 “ * ” 、 “ ? ” 、 “ [ ” 、 “ ] ” 及 “ ~ ” 等 字 符 将 不 再 展 开 使 多 义 性文 件 名 与 一 文 件 名 相 匹 配 。 如 果 由 于 某 些 原 因 , 你 在 文 件 名 中 使 用 了 这 些 特 殊字 符 , 这 个 特 殊 变 量 或 许 就 对 你 有 用 。 下 面 的 例 子 中 , 如 果 用 户 希 望 列 出 结 尾为 “ ? ” 的 文 件 名 answer? , 可 通 过 如 下 步 骤 : 首 先 , 用 户 设 置 noglob 变 量 来关 闭 上 述 特 殊 字 符 扩 展 特 性 , 然 后 再 列 出 文 件 名 。 可 以 看 到 , 目 前 命 令 行 上 的问 号(“ ? ”) 被 认 为 是 文 件 名 中 的 一 个 字 符 , 而 不 是 被 看 作 一 个 特 殊 的 字 符( 代表 任 意 一 字 符 ) 。

  • set noglob

  • ls answer? answer?

    1. 用 TCSH Shell 特 殊 设 置 用 户 系 统

与 BASH Shell 一 样 , 你 可 以 在 TCSH Shell 中 使 用 特 殊 Shell 变 量 去 配 置你 的 Linux 系 统 。 有 些 变 量 是 你 的 系 统 最 初 就 定 义 了 的 , 你 可 以 重 新 给 它 们 定义 一 个 新 的 值 ; 也 有 另 外 一 些 变 量 , 你 必 须 首 先 定 义 它 们 。 其 中 , 一 个 最 常 见的 特 殊 Shell 变 量 就 是 prompt 变 量 , 这 个 变 量 用 来 任 意 设 置

你 想 设 置 成 的 命 令 行 提 示 符 。 还 有 一 个 常 见 特 殊 Shell 变 量 就 是 history 变量 , 它 用 来 保 存 你 想 保 存 的 历 史 事 件 数 。

在 TCSH Shell 中 , 许 多 特 殊 变 量 与 BASH Shell 及 PDKSH Shell 中 的 特殊 变 量 名 相 同 , 且 功 能 相 似 。 有 些 特 殊 变 量 由 大 写 字 母 组 成 , 但 更 多 的 是 由 小写 字 母 组 成 。 变 量 EXINIT 及 TERM 仍 然 是 由 大 写 字 母 组 成 , 但 变 量 history 及cdpath 由 小 写 字 母 组 成 。 另 外 一 些 特 殊 变 量 完 成 相 同 的 功 能 , 但 使 用 时 却 有 很大 的 不 同 。 例 如 变 量 mail 同 时 具 有 BASH Shell 中 的 MAIL 、 MAILPATH 、MAILCHECK 这 三 个 变 量 的 功 能 。 这 些 变 量 在 表 16-3 中 列 出 。

16.5.1 变 量 promp t、 pro mpt2 及 prompt3

变 量 promp t、 prompt2 及 prompt3 设 置 你 的 命 令 行 提 示 符 。 你 可 以 把 命 令提 示 符 设 置 成 任 何 符 号 或 字 符 串 。 要 把 命 令 提 示 符 设 置 成 不 同 的 符 号 , 只 需 用set 命 令 把 所 要 设 置 的 符 号 赋 值 给 prompt 变 量 即 可 。 在 下 面 的 例 子 中 , 用 户 把符 号 “ + ” 赋 值 给 prompt 变 量 , 使 其 成 为 新 的 命 令 提 示 符 。

  • set prompt ="+"

+

Shell 提 供 一 组 预 定 义 符 , 用 这 些 预 定 义 符 可 以 更 容 易 地 配 置 你 的 命 令 提 示符 。 你 可 以 用 当 前 时 间 、 你 的 用 户 名 及 当 前 目 录 名 等 作 为 命 令 提 示 符 的 一 部 分 , 甚 至 可 以 用 将 要 输 入 的 命 令 的 历 史 事 件 号 来 作 为 命 令 提 示 符 。 每 个 预 定 义 符 由符 号“ % ”开头,例 如“ % /” 代 表 当 前 的 工 作 目 录 ,“ % t” 代 表 当 前 时 间 ,“ % n ” 代 表 你 的 用 户 名 , 而 “ % !” 将 显 示 出 将 要 输 入 命 令 的 历 史 事 件 号 。 在 下 面 的 例子 中 , 用 户 在 命 令 提 示 符 上 增 加 了 当 前 的 工 作 目 录 。

  • set prompt = "%/ >"

/home/dylan >

下 一 例 子 同 时 使 用 了 当 前 时 间 及 下 一 命 令 的 历 史 事 件 号 来 作 为 命 令 提 示

符 。

  • set prompt = "%t %! $"

这 里 列 出 TCS H Shel l 提 供 的 一 些 预 定 义 符 : 预 定 义 符 作 用

% / 当 前 目 录

% h 、 % !、 ! 当 前 将 要 输 入 命 令 的 历 史 事 件 号

% t 当 前 时 间

% n 当 前 用 户 名

% d 当 前 日 期 ( 用 星 期 几 表 示 )

% w 当 前 月 份

% y 当 前 年 份

变 量 prompt2 使 用 在 如 下 特 殊 情 况 : 当 一 个 命 令 需 用 几 行 才 能 完 成 输 入 时 , 增 加 的 行 将 用 prompt2 作 为 命 令 提 示 符 。 如 果 检 查 拼 写 特 性 被 激 活 , 命 令 提 示符 将 采 用 变 量 prompt3 的 值 。

16.5.2cdpath

变 量 cdpath 保 存 一 些 目 录 路 径 名 ,当 执 行 cd 命 令 时 ,shell 将 对 变 量 cdpath 中 指 定 的 目 录 路 径 名 进 行 搜 索 。这 些 目 录 路 径 名 形 成 一 个 列 表 ,正 如 TCSH Shell 中 赋 值 给 变 量 path 的 目 录 路 径 名 列 表 一 样 。 请 注 意 目 录 路 径 名 间 空 格 。

  • set cdpath=(/usr/chris/reports /usr/chris/letters)

16.5.3 history 和 savelist

前 面 已 经 介 绍 过 , 变 量 history 用 来 保 存 用 户 想 要 保 存 的 历 史 事 件 数 。 你 只需 赋 值 给 history 变 量 一 个 最 大 数 ( 最 大 的 历 史 事 件 号 ) , 当 达 到 最 大 历 史 事 件号 后 , 系 统 将 重 新 从 1 开 始 计 数 。 而 savelist 变 量 保 存 当 你 退 出 系 统 时 , 将 要保 存 到 .history 文 件 中 的 事 件 数 。 当 你 重 新 登 陆 系 统 时 , 这 些 事 件 将 成 为 你 系 统的 初 始 历 史 事 件 列 表 。

  • set history=20

  • set savelist=5

16.5.4mail

在 TCSH Shell 中 , mail 变 量 同 时 具 有 BASH Shell 或 PDKSH Shell 中 三个 变 量 MAIL 、 MAILCHECK 及 MAILPATH 的 功 能 与 特 性 。 TCSH Shell 中 的

变 量 mail 在 被 赋 值 时 , 需 给 其 赋 值 一 个 变 量 列 表 , 该 列 表 中 同 时 包 括 检 查 邮 件的 时 间 间 隔 及 检 查 的 邮 件 信 箱 文 件 所 在 的 目 录 路 径 名 。 要 确 定 检 查 邮 件 的 时 间间 隔 及 检 查 的 邮 件 信 箱 文 件 所 在 的 目 录 路 径 名 , 需 给 mail 变 量 赋 值 一 个 变 量 列表 , 该 列 表 由 圆 括 号 “ ( ) ” 括 起 来 的 一 系 列 字 符 串 组 成 , 字 符 串 与 字 符 串 之间 由 空 格 分 隔 开 。 表 中 第 一 项 是 一 个 数 字 , 它 用 来 设 定 检 查 邮 件 的 时 间 间 隔( 用秒 表 示 ) , 该 项 相 当 于 BASH Shell 中 变 量 MAILCHECK 中 保 存 的 值 。 余 下 的项 为 邮 件 信 箱 文 件 的 目 录 路 径 名 , 以 便 系 统 检 查 该 邮 件 信 箱 文 件 是 否 收 到 新 的邮 件 。 需 要 注 意 的 是 , 该 部 分 的 值 相 当 于 同 时 保 存 了 BASH Shell 或 Korn Shell 中 变 量 MAIL 、 MAILPATH 的 值 。

下 面 的 例 子 中 , ma il 变 量 被 设 置 成 : 每 20 分 钟 ( 1200 秒 ) 检 查 一 次 信 箱 , 要 检 查 的 邮 件 信 箱 文 件 在 目 录 /usr/mail/chris 下 。 列 表 中 的 第 一 项 为 1200 , 用来 赋 值 给 ma il 变 量 , 以 决 定 检 查 邮 件 时 间 间 隔 , 第 二 项 为 将 要 检 查 的 邮 件 信 箱文 件 的 路 径 名 。

  • set mail (1200 /usr/mail/chris)

你 也 可 以 非 常 方 便 地 给 mail 赋 值 多 个 邮 件 信 箱 文 件 目 录 路 径 。 在 下 面 的 例子 中 , 两 个 邮 件 信 箱 文 件 目 录 路 径 被 赋 值 给 变 量 ma il。 必 须 注 意 列 表 中 各 项 之间 的 空 格 。

  • Set mail (1200/usr/mail/chris/home/mail/chris) 16.6TCSH Shell 初 始 化 文 件 : .login 、 .tcshrc 及 .logout

TCSH Shell 有 三 个 初 始 化 文 件 : .login 、 .tcshrc 及 .logout。 这 些 文 件 根 据它 们 所 执 行 的 功 能 来 命 名 。 .login 是 登 陆 初 始 化 文 件 , 在 你 每 次 登 陆 时 都 自 动运 行 ; .logout 文 件 在 你 每 次 退 出 系 统 时 都 自 动 运 行 ; .tcshrc 文 件 是 Shell 初 始

化 文 件 ,在 你 每 次 进 入 TCSH Shell 时 都 自 动 运 行 ,可 以 是 在 直 接 登 陆 进 入 TCSH Shell , 或 是 在 另 外 一 种 Shell 下 , 用 tcsh 命 令 转 换 至 TCSH Shell 下 。

16.6.1.login

TCSH Shell 有 其 自 己 的 登 陆 初 始 化 文 件 .login , 该 文 件 中 包 含 一 些 Shell 命令 及 一 些 特 殊 环 境 变 量 的 定 义 ,它 们 用 来 配 置 用 户 的 Shell 。该 文 件 对 应 于 BASH Shell 及 PDKSH Shell 中的 .profile 文 件 。

.login 文 件 通 过 命 令 setenv 给 一 些 特 殊 环 境 变 量 赋 值 , 例 如 变 量 TERM 。你 可 以 用 任 何 编 辑 器 编 辑 .login 文 件 来 改 变 这 些 特 殊 环 境 变 量 的 值 , 也 可 以 在该 文 件 中 增 加 新 的 环 境 变 量 , 但 是 , 必 须 注 意 : 在 TCSH Shell 中 , 用 来 给 特殊 环 境 变 量 赋 值 的 命 令 是 setenv 。 下 面 的 例 子 中 , 变 量 EXINIT 被 赋 值 , 从 而使 vi 编 辑 器 具 有 显 示 行 号 及 自 动 缩 进 特 性 。

  • setenv EXINIT 'set nu ai'

在 编 辑 .login 文 件 的 时 候 必 须 非 常 小 心 , 稍 不 注 意 可 能 导 致 变 量 赋 值 不 正 确或 根 本 没 被 赋 值 。 因 此 , 在 对 .login 文 件 进 行 编 辑 之 前 , 备 份 .login 文 件 是 明 智而 必 要 的 。

如 果 你 已 经 更 改 了 .login 文 件 , 并 希 望 你 的 更 改 在 当 前 登 陆 下 生 效 , 你 需 要重 新 运 行 该 文 件 。 此 时 , 你 需 用 source 命 令 。 source 实 际 上 可 以 运 行 任 何 初始 化 文 件 ,包 括 .tcshrc 及 .logout 文 件 等 。在 下 面 的 例 子 中 ,用 户 重 新 运 行 了 .login 文 件 。

  • source .login

如 果 你 也 想 在 你 的 Linux 系 统 上 使 用 PDKSH Shell , 你 需 在 .login 文 件 中 定

义 一 名 为 ENV 的 变 量 , 并 把 PDKSH Shell 初 始 化 文 件 赋 值 给 它 。 在 登 陆 进 入TCSH Shell 之 后 , 如 果 你 想 从 TCSH Shell 进 入 PDKSH Shell , 系 统 将 会 找 到PDKSH Shell 初 始 化 文 件 , 并 执 行 该 初 始 化 文 件 。 下 面 列 出 了 .login 文 件 的 清单 , 可 以 看 到 , 文 件 中 最 后 一 命 令 setenv ENV $HOME/.kshrc 就 是 把 PDKSH Shell 初 始 化 文 件 赋 值 给 变 量 ENV 。

.login 文 件 清 单

setenv term vt100 setenv EXINIT 'set nu ai'

setenv ENV $HOME/.kshrc

16.6.2.tcshrc

在 你 每 次 进 入 TCSH Shell 或 在 TCSH Shell 创 建 任 何 子 Shell 时 , 系 统 都会 运 行 .tcshrc 初 始 化 文 件 。 如 果 TCSH Shell 就 是 你 登 陆 后 的 Shell, 在 登 陆及 .login 文 件 运 行 后 , .tcshrc 文 件 就 会 运 行 。 如 果 你 是 从 另 外 一 个 Shell 进 入TCSH Shell , .tcshrc 文 件 就 会 被 自 动 运 行 , 该 文 件 中 的 一 些 变 量 或 别 名 就 会 被定 义 并 生 效 。

实 际 上 , 初 始 化 文 件 .tcshrc 在 你 每 次 创 建 Shell 时 ( 例 如 运 行 Shell 脚 本 程序 时 ) , 都 会 自 动 执 行 。 换 句 话 说 , 每 创 建 一 个 子 Shell , .tcshrc 文 件 就 会 被自 动 运 行 。 这 意 味 着 , 在 初 始 化 文 件 .tcshrc 中 定 义 的 局 部 变 量 会 被 输 出 至 任 何子 Shell 。 尽 管 一 些 “ 用 户 级 定 义 ” ( user-defined ) 特 殊 变 量 , 例 如 history, 是 局 部 变 量 , 但 是 , 它 们 会 在 每 个 子 Shellz 中 被 定 义 。 因 此 , 从 这 个 意 义 上 说 ,

变 量 history 是 为 每 个 子 Shell 设 置 的 , 尽 管 每 个 子 Shell 都 有 其 自 己 的 局 部 变量 。 你 甚 至 可 以 在 一 个 子 Shell 中 改 变 局 部 变 量 history 的 值 , 但 它 不 会 影 响 其它 子 Shell 的 值 。 与 BASH Shell 中 一 样 , Shell 初 始 化 文 件 中 定 义 的 变 量 可 以用 export 命 令 进 行 变 量 输 出 。在 第 15 章 中 已 经 讨 论 过 ,在 BASH Shell 及 PDKSH Shell 中 输 出 的 变 量 仅 传 递 该 变 量 的 一 个 拷 贝 至 其 子 Shell , 改 变 这 一 拷 贝 的 值并 不 改 变 该 输 出 变 量 本 身 的 值 。

.tcshrc 文 件 中 也 包 括 一 些 别 名 的 定 义 及 一 些 用 来 改 变 Shell 特 性 的 特 殊 开

关 变 量 。 别 名 和 特 性 变 量 是 在 Shell 内 局 部 定 义 的 , 但 Shell 会 在 每 个 子 Shell 中 定 义 它 们 的 一 个 拷 贝 。 因 此 , .tcshrc 文 件 通 常 定 义 一 些 为 rm 、 cp 及 mv 命令 等 定 义 的 别 名 。 下 面 的 .tcshrc 文 件 中 包 括 了 一 些 标 准 的 定 义 。

.tcshrc 文 件 清 单

set shell=/usr/bin/csh

set path=$PATH(/bin /usr/bin .)

set cdpath=(/home/chris/reports /home/chris/letters)

set prompt = "!$cwd >" set history =20

set ignoreeof set noclobber

alias rm "rm -i" alias mv "mv -i"

alais cp "cp -i"

局 部 变 量 与 环 境 变 量 不 同 , 它 们 是 由 set 命 令 定 义 的 。 任 何 在 .tcshrc 中 定义 的 局 部 变 量 必 须 用 set 命 令 ; 任 何 定 义 的 环 境 变 量 必 须 用 setenv 命 令 去 定 义 , 且 必 须 在 文 件 .login 文 件 中 定 义 , 例 如 变 量 TERM 。 下 面 是 另 外 一 些 在 .tcshrc 文 件 中 定 义 的 局 部 变 量 。 请 注 意 变 量 history 及 noclobber 是用 set 命 令 定 义 的 。

set history=20 set noclobber

你 可 以 编 辑 上 述 任 何 变 量 , 并 给 它 们 重 新 赋 值 。 但 是 , 当 给 path 及 cdpath 变 量 增 加 目 录 路 径 时 , 必 须 记 住 : 这 些 目 录 路 径 要 用 圆 括 号 “ ()” 括 起 来 , 且每 给 目 录 路 径 之 间 要 用 空 格 分 隔 开 。

如 果 你 增 加 了 新 的 目 录 路 径 名 , 你 必 须 确 保 目 录 路 径 与 目 录 路 径 之 间 已 用空 格 分 隔 开 。 如 果 你 对 .tcshrc 文 件 作 了 任 何 更 改 , 并 想 使 这 些 更 改 在 当 前 Shell 下 生 效 , 记 住 必 须 用

source 命 令 重 新 运 行 该 文 件 。

  • source .tcshrc

16.6.3.logout

.logout 文 件 也 是 一 初 始 化 文 件 , 但 该 文 件 是 在 用 户 退 出 系 统 时 执 行的 。 .bash_logout 也 是 一 个 初 始 化 文 件 , 当 用 户 退 出 系 统 时 , 将 执 行 该 文 件 。当 你 退 出 时 , 你 可 以 指 定 系 统 执 行 你 想 做 的 操 作 。 .logout 文 件 不 是 用 来 定 义 变量 或 别 名 的 , 而 是 通 常 由 一 些 Shell 命 令 组 成 的 关 机 程 序 , 也 就 是 关 机 时 你 想

要 系 统 做 的 一 些 操 作 。 例 如 , 一 个 常 见 的 操 作 是 退 出 时 检 查 后 台 运 行 的 进 程 ; 另 一 常 见 操 作 是 希 望 系 统 退 出 时 清 屏 , 然 后 向 用 户 发 出 祝 福 或 结 束 信 息 。

与 .login 文 件 一 样 , 你 可 以 在 .logout 文 件 中 增 加 自 己 的 Shell 命 令 语 句 , 用vi 编 辑 器 你 可 以 改 变 退 出 时 系 统 向 用 户 发 出 的 信 息 或 增 加 其 它 操 作 与 功 能 。 在下 面 的 例 子 中 ,用 户 的 .logout 文 件 中 有 clear 及 echo 两 条 命 令 ,当 用 户 退 出 时 , clear 命 令 将 首 先 进 行 清 屏 , 然 后 echo 命 令 向 用 户 显 示 “ Good-bye for now ” 信 息 。

.logout 文 件 清 单

clear

echo "Good-bye for now"

TCSH Shell 程 序 设 计

与 BASH Shell 及 PDKSH Shell 一 样 , TCSH Shell 也 具 有 和 其 它 程 序 设 计语 言 一 样 的 编 程 能 力 。 你 可 以 定 义 变 量 并 赋 值 给 它 们 , 你 也 可 以 在 脚 本 程 序 中定 义 变 量 , 键 入 Linux 命 令 并 执 行 这 些 脚 本 程 序 。 TCSH Shell 还 提 供 了 循 环 、条 件 等 控 制 结 构 。 其 中 , 循 环 结 构 用 来 多 次 执 行 某 些 Linux 命 令 ; 条 件 结 构 用来 控 制 、 选 择 你 要 执 行 的 命 令 。 你 也 可 以 在 程 序 中 截 获 并 处 理 中 断 。

TCSH Shell 与 其 它 Shell 的 不 同 之 处 在 于 它 的 控 制 结 构 更 接 近 程 序 设 计 语言 ,并 符 合 程 序 设 计 的 规 范 。例 如 ,TCSH Shell 的 条 件 控 制 结 构 是 被 赋 值 以 true

或 false 的 一 个 表 达 式 , 不 是 一 个 Linux 命 令 。 TCSH Shell 中 的 表 达 式 使 用 的算 子 与 C 语 言 程 序 设 计 中 的 表 达 式 使 用 的 算 子 相 同 。 你 可 以 进 行 各 种 不 同 的 赋值 操 作 、 算 术 运 算 、 比 较 运 算 及 逻 辑 运 算 等 。 你 可 以 声 明 数 字 型 变 量 , 然 后 在上 述 操 作 、 运 算 中 使 用 它 们 。

TCSH Shell 变 量 、 脚 本 程 序 及 参 数

你 已 经 知 道 , 在 TCSH Shell 中 , 可 以 象 在 BASH Shell 及 PDKSH Shell 中 那 样 使 用 Shell 变 量 。 你 可 以 在 Shell 中 定 义 变 量 , 并 赋 值 给 它 们 , 同 时 , 也可 以 引 用 脚 本 程 序 命 令 行 参 数 。 与 BASH Shell 进 行 变 量 输 出 一 样 , 你 也 可 以在 程 序 中 定 义 环 境 变 量 。 但 TCSH Shell 的 不 同 之 处 在 于 在 定 义 变 量 时 必 须 定义 你 所 定 义 的 变 量 类 型 。 在 TCSH Shell 中 , TCSH Shell 用 se t 、 @ 及 setenv 命 令 来 定 义 变 量 。 TCSH Shell 还 允 许 你 定 义 数 字 型 变 量 及 数 组 。 @ 命 令 用 来 定义 数 字 型 变 量 , 用 它 们 可 以 完 成 算 术 运 算 。 圆 括 号 “ ( ) ” 用 来 定 义 并 引 用 数组 。

进 行 TCSH Shell 脚 本 程 序 设 计 基 本 上 与 BASH Shell 差 不 多 , 但 也 有 一 些重 要 差 别 。 例 如 , TCSH Shell 脚 本 程 序 的 第 一 行 第 一 列 必 须 是 “ # ” 号 ; 尽 管echo 命 令 可 以 用 来 进 行 显 示 、 输 出 , 但 没 有 用 来 处 理 输 入 的 read 命 令 , 而 需用 标 准 输 入 重 定 向 操 作 来 给 变 量 赋 值 。

TCSH She ll 变 量

TCSH Shell 中 , 在 使 用 一 个 变 量 之 前 , 你 必 须 首 先 声 明 该 变 量 。 你 可 以 用

set 命 令 , 然 后 是 一 个 变 量 名 来 声 明 一 个 变 量 。 变 量 名 可 以 是 由 任 何 一 组 字 母 组

成 的 字 符 或 字 符 串 , 包 括 下 划 线 。 变 量 名 也 可 以 包 含 数 字 , 但 数 字 不 能 是 变 量名 的 第 一 个 字 母 。 变 量 名 中 不 能 有 如 下 字 符 , 如 “ !” 号 、 “ & ” 字 符 及 空 格 等 。这 些 变 量 是 Shell 保 留 的 , 只 能 被 Shell 自 己 使 用 。 变 量 名 也 不 能 包 含 几 个 英 文单 词 , 因 为 系 统 要 在 空 格 处 分 解 命 令 行 , 因 此 空 格 是 命 名 行 中 的 各 项 之 间 的 分隔 符 。 下 面 的 例 子 声 明 了 变 量 greeting, 你 可 以 用 unset 命 令 取 消 该 变 量 的 定义 。

  • set greeting

你 这 样 用 set 命 令 给 一 个 变 量 赋 值 : 首 先 键 入 set 命 令 , 然 后 键 入 变 量 名 及赋 值 操 作 符 “ = ” , 最 后 是 变 量 要 赋 与 的 值 。 任 何 字 符 或 字 符 串 都 可 以 赋 值 给 变量 。 下 面 的 例 子 中 , 字 符 串 “ hello ” 被 赋 值 给 变 量 greeting 。

  • set greeting="hello"

在 TCSH Shell 的 赋 值 操 作 中 , 你 要 么 在 赋 值 操 作 符 “ = ” 的 两 边 同 时 加 上空 格 或 根 本 不 用 加 人 空 格 。 赋 值 操 作 :

  • set greeting ="hello"

将 失 败 , 因 为 在 赋 值 操 作 “ = ” 之 前 键 入 了 空 格 , 而 在 其 后 却 没 有 。

你 可 以 键 入 不 带 任 何 参 数 的 set 命 令 来 得 到 所 有 已 定 义 的 变 量 列 表 。 在 下 面的 例 子 中 , 用 户 用 set 命 令 列 出 了 已 定 义 的 所 有 变 量 及 它 们 的 值 。

  • set

greeting hello poet Virgil

与 BASH Shell 一 样 , 符 号 “ $ ” 是 一 个 特 殊 操 作 符 , 它 用 来 引 用 一 个 变 量

的 值 , 该 引 用 返 回 一 个 变 量 的 值 , 通 常 是 一 组 字 符 , 然 后 用 这 组 字 符 代 替 变 量名 。 这 样 , 任 何 在 变 量 名 前 有 “ $ ” 字 符 的 地 方 , 变 量 名 将 由 变 量 的 值 所 代 替 。

在 下 面 的 例 子 中 , Shell 变 量 greeting 被 赋 以 值“ hello ”,然后该值被用作 echo

命 令 的 参 数 。 于 是 , echo 命 令 将 把 这 组 字 符 在 屏 幕 上 显 示 出 来 。

  • echo $greeting hello

TCSH Shell 脚 本 程 序 : 输 入 与 输 出

你 可 以 在 脚 本 程 序 中 方 便 地 定 义 和 使 用 各 种 变 量 。 正 如 下 面 的 例 子 一 样 , 你 可 以 用 文 本 编 辑 器 在 脚 本 程 序 中 输 入 Linux 命 令 及 进 行 赋 值 操 作 。 你 可 以 设置 文 件 的 属 性 为 “ 可 执 行 性 ” ( executable ) , 然 后 , 如 同 执 行 一 个 Shell 命 令一 样 , 你 可 以 在 命 令 提 示 符 后 直 接 键 入 文 件 名 去 运 行 该 文 件 。 记 住 要 设 置 文 件的 可 执 行 权 限 , 可 以 用 chmod u+x 命 令 或 绝 对 方 式 chmod 700 命 令 去 设 置 它 。在 脚 本 程 序 中 , 你 可 以 使 用 echo 命 令 进 行 数 据 输 出 , 但 是 , 变 量 的 数 据 读 取是 通 过 重 定 向 标 准 输 入 来 读 入 的 。在 TCSH Shell 中 ,没 有 与 BASH Shell 中 read 命 令 相 类 似 的 命 令 。

TCSH Shell 将 检 查 脚 本 程 序 的 第 一 个 字 符 , 以 决 定 该 文 件 是 否 是 TCSH Shell 下 的 脚 本 程 序 。 必 须 记 住 , 所 有 的 TCSH Shell 脚 本 程 序 必 须 以 符 号 “ # ” 为 程 序 的 第 一 行 第 一 个 字 符 , 系 统 将 依 此 来 判 断 该 脚 本 程 序 是 否 是 一 个 TCSH Shell 脚 本 程 序 。 注 意 下 面 脚 本 程 序 greet 的 首 字 符 “ # ” 。 同 时 , 符 号 “ # ” 不只 是 放 在 文 件 的 第 一 行 第 一 字 符 , 它 可 以 和 一 个 普 通 字 符 一 样 , 放 在 文 件 的 任何 地 方 。

greet 脚 本 程 序 清 单 :

#

#Script to output hello greeting

set greeting="hello"

echo The value of greeting is $greeting

>chmod u+x greet

>greet

The value of greeting is hello

set 命 令 与 重 定 向 操 作 符 “ $< ” 组 合 将 读 取 用 户 从 标 准 输 入 设 备 输 入 的 任 何字 符 。 下 面 的 例 子 中 , greeting 变 量 读 取 用 户 输 入 的 数 据 :

  • set greeting = $<

在 用 echo 命 令 进 行 数 据 输 入 时 , 你 可 以 把 你 的 输 入 字 符 串 与 输 入 提 示 字 符串 放 置 在 同 行 上 。

TCSH Shell 在 echo 命 令 中 使 用 特 殊 选 项 -n 来 消 除 输 出 字 符 串 窜 尾 的 换 行符 , 光 标 将 仍 然 停 留 在 输 出 字 符 串 窜 尾 上 。

  • echo -n Please enter a greeting:

如 果 希 望 在 你 的 输 入 提 示 符 字 符 尾 包 含 一 个 空 格 字 符 , 你 需 在 输 入 特 殊 符后 键 入 格 , 然 后 用 双 引 号 括 起 来 。 例 如 :

  • echo -n "Please enter a greeting: "

下 面 的 脚 本 程 序 greetpt 中 , 在 输 入 数 据 时 , TCSH Shell 将 使 输 入 提 示 符与 输 入 数 据 在 同 一 行 上 。

greetpt 脚 本 清 单 :

#

echo -n "Please enter a greeting: "

set greeting=$<

echo "The greeting you entered was $greeing"

  • greetpt

P lease enter a greeting: hello The greeting you entered was hello

>

参 数 数 组 : argv

当 一 个 脚 本 程 序 被 运 行 时 , 所 有 命 令 行 的 单 词 将 由 空 格 符 分 隔 为 不 同 的 项 , 这 些 项 将 被 保 存 在 一 个 称 之 为 argv 的 数 组 元 素 之 中 , 元 素 argv [ 0 ] 保 存 命 令名 , 从 argv [ 1 ] 开 始 , 每 个 元 素 将 保 存 命 令 行 上 的 每 个 参 数 。 对 所 有 的 Shell 脚 本 程 序 , argv [ 0 ] 将 始 终 保 存 Shell 脚 本 程 序 名 。 和 其 它 一 些 数 组 一 样 , 你可 以 用 操 作 算 子“ $ ” 去 存 取 数 组 argv 中 的 所 有 元 素( 命 令 行 参 数 ),$arg v[ 1 ] 将 存 取 argv 数 组 中 的 第 二 个 元 素 , 即 命 令 行 第 一 个 参 数 。 如 果 不 止 输 入 一 个 参数 , 你 可 以 通 过 数 组 argv 存 取 命 令 行 中 的 每 个 参 数 。 在 下 面 的 例 子 中 , myargs 脚 本 程 序 在 屏 幕 上 打 印 出 命 令 行 上 的 四 个 参 数 。

myargs 脚 本 程 序 清 单 :

#

echo "The first argument is: $argv[ 1 ] " echo "The second argument is: $argv [ 21 ] " echo "The third argument is: $argv[ 3 ] "

echo "The fourth argument is: $argv [ 4 ] "

  • myargs Hello Hi yo "How are you" The first argument is: Hello

The second argument is: Hi The third argument is: yo

The fourth argument is: How are you

>

argv 数 组 中 的 元 素 可 以 被 简 写 为 符 号 “ $ ” 加 元 素 的 序 号 。 于 是 $arg v[ 1 ] 就 可 以 简 写 为“ $1 ”。因 此 ,TCSH Shell 脚 本 程 序 对 命 令 行 参 数 的 引 用 与 BASH Shell 及 PDKSH Shell 对 参 数 的 引 用 类 似 。 特 殊 参 数 变 量 arg v[ * ] 将 引 用 命 令行 上 所 有 的 参 数 , $argv[ * ] 可 以 简 写 为 “ $* ” 。 我 们 可 以 注 意 到 , 这 和 BASH Shell 中 引 用 所 有 变 量 的 用 法 相 同 。

参 数 变 量 #argv 保 存 命 令 行 上 所 有 输 入 参 数 的 个 数 。 这 在 为 一 个 脚 本 程 序 指定 固 定 的 参 数 数 量 时 很 有 用 。 例 如 : 这 个 数 可 以 用 来 核 实 用 户 是 否 正 确 地 输 入了 需 要 的 参 数 数 。下 面 的 脚 本 程 序 arglist 演 示 了 特 殊 参 数 变 量 arg v[ * ]及 #argv 的 使 用 。 程 序 首 先 显 示 命 令 行 上 输 入 的 参 数 的 个 数 , 然 后 在 屏 幕 上 显 示 出 输 入的 这 些 参 数 。

arglist 脚 本 程 序 清 单 :

#

echo "The number of arguments entered is $# argv"

echo "The list of arguments is: $argv [ *] "

  • arglist Hello Hi yo

The number of arguments entered is: 3 The list of arguments is: Hello Hi yo

>

数 字 型 变 量 : @

在 TCSH Shell 中 , 你 可 以 用 @ 命 令 而 不 是 set 命 令 去 声 明 数 字 型 变 量 , 然后 ,你 可 以 用 这 些 变 量 进 行 算 术 运 算 、比 较 运 算 、逻 辑 运 算 等 。在 这 方 面 , TCSH Shell 程 序 设 计 与 其 它 程 序 设 计 语 言 类 似 。 数 字 变 量 与 字 符 串 变 量 是 两 种 差 别 较大 的 变 量 , 它 们 的 处 理 方 式 也 有 很 大 的 不 同 。 你 不 能 用 set 命 令 去 给 一 个 数 字型 变 量 赋 值 。 @ 命 令 由 关 键 字 “ @ ” 、 变 量 名 、 赋 值 操 作 符 “ = ” 及 算 术 表 达 式组 成 。 下 面 的 例 子 声 明 了 一 个 数 字 型 变 量 num 并 把 10 赋 值 给 该 变 量 。

  • @ num = 10

你 可 以 使 用 各 种 操 作 算 子 , 如 “ + ” 等 算 术 操 作 算 子 。 它 们 的 用 法 与 前 面 介绍 的 awk 命 令 及 C 程 序 设 计 中 的 操 作 算 子 的 用 法 相 同 。 表 达 式 中 可 以 是 任 何 算术 、 比 较 或 逻 辑 表 达 式 。 你 也 可 以 用 圆 括 号 去 创 建 更 复 杂 的 表 达 式 。 表 达 式 中的 操 作 数 必 须 用 空 格 把 它 们 与 操 作 算 子 分 隔 开 , 例 如 10*5 是 一 个 无 效 的 表 达式 , 必 须 加 入 空 格 , 写 成 10 * 5 。 你 也 可 以 在 表 达 式 中 使 用 数 字 型 变 量 作 为 操作 数 。 下 面 的 例 子 中 , count 被 声 明 为 一 数 字 型 变 量 , 然 后 表 达 式 中 使 用 了 该变 量 。 请 注 意 : 变 量 count 前 使 用 了 “ $ ” 操 作 符 , 以 使 表 达 式 使 用 的 是 变 量 的值 3 而 不 是 变 量 名 。 表 16-4 是 数 字 型 操 作 算 子 列 表 。

  • @ count = 3

  • @ num = 2 * ($count + 10)

  • echo $num 26

>

环 境 变 量 : setenv

TCSH Shell 中 有 两 类 变 量 : 局 部 变 量 及 环 境 变 量 。 局 部 变 量 仅 仅 局 限 于 它所 声 明 的 Shell 的 内 部 , 而 环 境 变 量 类 似 于 全 局 变 量 , 它 的 作 用 范 围 包 括 Shell 本 身 及 其 创 建 的 任 何 子 Shell , 但 不 包 括 其 父 Shell 。 环 境 变 量 有 setenv 命 令 定义 , 你 可 以 用 如 下 方 式 给 一 个 环 境 变 量 赋 值 : setenv 命 令 , 然 后 是 变 量 名 , 最后 是 变 量 将 要 赋 予 的 值 , 其 中 没 有 任 何 操 作 算 子 。 下 面 的 例 子 中 , greeting 环境 变 量 被 赋 值 以 “ He llo ” 。

  • setenv greeting Hello

无 论 什 么 时 候 调 用 一 个 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 也 有 一 组 控 制 结 构 , 这组 控 制 结 构 能 让 你 控 制 脚 本 程 序 中 命 令 的 执 行 , 例 如 循 环 和 条 件 控 制 结 构 。 其中 , 循 环 结 构 用 来 多 次 执 行 某 些 Linux 命 令 , 条 件 结 构 用 来 控 制 、 选 择 你 要 执行 的 命 令 ; while 及 if 控 制 结 构 是 更 常 用 的 控 制 结 构 , while 控 制 结 构 用 来 重 复执 行 命 令 ,而 if 控 制 结 构 根 据 表 达 式 的 值 的 真 假 来 选 择 执 行 相 应 的 命 令 ;switch 和 foreach 控 制 结 构 更 是 为 适 应 特 殊 目 的 而 提 供 的 两 种 控 制 结 构 , switch 控 制结 构 把 表 达 式 的 值 与 一 组 该 表 达 式 可 能 的 值 相 比 较 , 然 后 再 执 行 相 应 的 命 令 。 foreach 结 构 是 一 种 有 限 次 循 环 结 构 , 每 次 循 环 时 , 它 把 一 系 列 值 ( 有 限 个 ) 中的 一 个 值 赋 值 给 变 量 , 然 后 执 行 循 环 体 内 的 命 令 , 直 到 这 些 值 全 被 赋 值 完 为 止 。 TCSH Shell 与 其 它 Shell 的 不 同 之 处 在 于 它 的 控 制 结 构 提 供 了 比 其 它 Shell

程 序 设 计 语 言 更 多 的 格 式 。 TCSH Shell 控 制 结 构 的 测 试 条 件 是 一 个 被 赋 值 以 真

( True )或 假( False )的 表 达 式 ,而 不 是 一 个 Linux 命 令 。TCSH Shell 与 BASH Shell 的 一 个 最 大 不 同 之 处 在 于 TCSH Shell 结 构 不 能 用 进 行 重 定 向 与 管 道 输出 , 它 们 是 更 严 谨 的 控 制 结 构 , 以 控 制 命 令 的 执 行 。

测 试 表 达 式

if 和 while 控 制 结 构 用 表 达 式 作 为 它 们 的 测 试 条 件 。 当 表 达 式 的 值 为 非 0 值时 测 试 条 件 为 真 ( true ) , 当 表 达 式 的 值 为 0 时 为 假 ( false ) 。 在 TCSH Shell 中 , 比 较 及 等 号 等 符 号 通 常 被 方 便 地 用 来 在 测 试 表 达 式 中 , 因 为 这 种 表 达 式 的

结 果 通 常 是 1 ( true ) 或 0 ( false ) 。 你 可 以 在 表 达 式 中 使 用 各 种 操 作 算 子 。 测试 表 达 式 也 可 以 是 算 术 或 字 符 串 比 较 , 但 字 符 串 比 较 仅 可 以 用 等 号 或 不 等 号 。

与 BASH Shell 及 PDKSH Shell 不 一 样 , 在 TCSH Shell 中 , 你 必 须 用 圆括 号 “ ( ” 和 “ ) ” 把 if 及 while 控 制 结 构 中 的 测 试 表 达 式 括 起 来 。 下 面 的 例子 中 的 测 试 表 达 式 用 来 判 断 两 个 字 符 串 是 否 相 等 。

if ( $greeting == "hi" ) then echo Informal Greeting

endif

TCSH Shell 中 有 一 些 测 试 算 子 用 来 测 试 字 符 串 是 否 与 字 符 串 或 正 则 表 达 式

( Regular expression ) 相 等 或 不 等 。 算 子 “ == ” 与 “ != ” 分 别 用 来 判 断 两 字符 串 相 等 或 不 等 。 算 子 “ =~ ” 与 “ !~ ” 分 别 用 来 判 断 字 符 串 与 正 则 表 达 式 是 否相 匹 配 或 判 断 两 者 之 间 是 否 不 匹 配 。 这 里 的 正 则 表 达 式 可 以 包 括 任 何 Shell 特殊 字 符 。 在 下 面 的 例 子 中 , 如 果 变 量 greeting 的 值 是 任 何 以 大 写 字 母 H 或 小 写字 母 h 开 头 的 字 符 串 , 那 么 它 将 和 正 则 表 达 式 [ Hh ] * 相 匹 配 。

if ( $greeting =~ [ Hh ] * ) then echo Informal Greeting

endif

与 BASH Shell 一 样 , TCSH Shell 也 有 几 个 特 殊 算 子 来 测 试 文 件 的 存 取 状况 。许 多 这 些 操 作 算 子 是 相 同 的 。在 下 面 的 例 子 中 , if 命 令 用 来 测 试 文 件 mydata 是 否 是 可 读 的 。表 16-5 中 文 件 存 取 状 况 的 一 些 特 殊 算 子 。表 16-6 列 出 了 TCSH Shell 中 的 一 些 命 令 与 变 量 。

if ( -r mydata ) then

echo Informal Greeting endif

Shell 条 件 控 制 结 构 : if-then 、 if-then-else 及 switch

TCSH Shell 有 一 组 条 件 控 制 结 构 , 这 些 条 件 结 构 用 来 控 制 、 选 择 你 要 执 行的 Linux 命 令 。 这 些 条 件 控 制 结 构 的 用 法 大 部 分 与 在 BASH Shell 中 的 条 件 控 制结 构 的 用 法 相 类 似 , 但 有 一 些 有 重 大 差 别 。 例 如 , TCSH Shell 中 的 if 条 件 控 制结 构 以 关 键 词 endif 为 结 束 ; switch 控 制 结 构 中 使 用 case 关 键 词 , 并 且 它 以 关键 词 endsw 为 结 束 , 而 在 各 case 之 间 用 breaksw 来 表 明 一 个 case 段 的 结 束 。此 外 , 有 两 种 if( 条 件 ) 控 制 结 构 : 一 种 是 简 单 型 条 件 控 制 结 构 , 它 仅 用 来 执

行 一 条 命 令 ; 另 一 种 是 复 杂 型 条 件 控 制 结 构 , 它 可 以 执 行 好 几 个 命 令 或 可 选 命令 。 简 单 型 条

件 控 制 结 构 由 关 键 词 if 、 然 后 是 测 试 条 件 及 单 个 Linux 命 令 组 成 。 复 杂 型 的条 件 控 制 结 构 以

关 键 词 endif 为 结 束 。TCSH Shell 的 条 件 控 制 结 构 的 用 法 在 表 16-7 中 列 出 。

if-then

if-then 控 制 结 构 可 以 为 几 个 Linux 命 令 设 置 条 件 , 该 条 件 是 一 个 表 达 式 。如 果 表 达 式 的 值 不 是 0 , 则 表 达 式 的 值 为 真 ( true) , 于 是 if 控 制 结 构 内 的 命 令将 被 执 行 ; 如 果 表 达 式 的 值 是 0 , 则 表 达 式 的 值 为 假 ( false ) , if 控 制 结 构 内的 命 令 将 不 被 执 行 ;if-then 控 制 结 构 由 关 键 词 if 开 头 ,关 键 词 后 是 由 圆 括 号“( ”、“ ) ” 括 起 来 的 一 个 表 达 式 , 紧 接 其 后 是 关 键 词 then , 然 后 , 你 可 以 在 此 后 的行 上 加 入 任 何 条 Linux 命 令 。 关 键 词 end if 将 结 束 if 控 制 结 构 。 需 要 注 意 的 是 :

在 BASH Shell 中 , 关 键 词 then 是 单 独 另 起 一 行 , 而 在

TCSH Shell 中 , then 和 表 达 式 在 同 一 行 上 。 if-then 控 制 结 构 的 句 法 如 下 :

if ( Expression ) then Commands

endif

下 面 的 ifls 脚 本 程 序 将 列 出 文 件 及 其 大 小 。 如 果 你 在 程 序 提 示 符 后 键 入 字 符“ s ” , 当 前 目 录 下 的 每 个 文 件 及 该 文 件 所 占 用 的 块 数 将 会 被 列 出 , 如 果 用 户 输入 字 符 “ s ” 以 外 的 任 何 字 符 , if 测 试 条 件 将 不 成 立 , 脚 本 程 序 将 不 执 行 任 何 命令 。

ifls 脚 本 程 序 清 单 :

#

echo -n "Please enter option: " set option=$<

if ( $option == "s" ) then echo Listing files by size ls -s

endif

  • ifls

P lease enter option: s Listing files by size

total 2

1 monday 2 today

>

if-then-else

通 常 , 你 需 要 在 一 个 表 达 式 值 的 真 、 假 这 两 者 之 间 作 出 选 择 , 而 关 键 词 else 允 许 if 控 制 结 构 在 上 述 两 者 之 间 作 出 选 择 。 如 果 表 达 式 的 值 为 真 ( true ) , 在紧 跟 测 试 表 达 式 及 关 键 词 then 之 后 的 命 令 将 立 即 被 执 行 , 如 果 表 达 式 的 值 为 假

( false ) , 在 紧 跟 关 键 词 else 之 后 的 命 令 将 被 执 行 。 if-then-else 控 制 结 构 的句 法 如 下 :

if ( Expression)then Commands

else Commands endif

下 面 的 脚 本 程 序 elsels 在 执 行 ls 命 令 的 时 候 将 有 两 种 可 能 的 选 项 , 在 列 出当 前 目 录 下 的 文 件 时 , 或 者 是 同 时 列 出 文 件 的 大 小 , 或 者 是 列 出 文 件 的 所 有 信息 。 如 果 用 户 在 程 序 提 示 符 后 键 入 字 符 “ s ” , 将 同 时 列 出 文 件 的 大 小 , 否 则 列出 文 件 的 所 有 信 息 。需 要 注 意 的 是 ,请 读 者 注 意 该 脚 本 程 序 与 前 一 章 BASH Shell 中 介 绍 的 elsels 脚 本 程 序 的 句 法 及 结 构 有 什 么 不 同 。

elsels 脚 本 程 序 清 单 :

#

echo Enter s to list file sizes,

echo otherwise all file information is listed. echo -n "Please enter option: "

echo option=$<

if ($option == "s" ) then ls -s

else ls -l endif

echo Good-bye

  • elsels

Enter s to list file sizes,

otherwise all file information is listed.

P lease enter option: s total 2

1 monday 2 today Good-bye

>

switch

switch 控 制 结 构 从 可 能 的 几 个 结 果 中 选 择 相 应 要 执 行 的 命 令 。 它 和 BASH Shell 中 的 case 控 制 结 构 非 常 类 似 , 它 根 据 一 个 字 符 串 与 几 个 可 能 的 模 式

( pattern ) 之 间 的 比 较 结 果 作 出 选 择 。 每 个 可 能 的 模 式 都 对 应 于 一 组 命 令 , 当

找 到 与 字 符 串 匹 配 的 模 式 的 时 候 , 与 该 模 式 对 应 的 命 令 将 被 执 行 。 switch 控 制结 构 以 关 键 词 switch 开 头 , 紧 接 其 后 是 用 圆 括 号 括 起 来 的 字 符 串 , 该 字 符 串 通常 是 来 自 赋 值 了 的 变 量 。 此 后 是 一 组 模 式 , 每 一 个 模 式 之 前 是 关 键 词 case , 其后 以 符 号 “ :” 结 束 。 与 模 式 对 应 的 命 令 在 符 号 “ :” 后 列 出 , 且 这 些 命 令 以 关 键词 breaksw 结 束 。 最 后 以 关 键 词 endsw 结 束 switch 控 制 结 构 。 switch 控 制 结构 的 句 法 如 下 :

switch ( test-string ) case pattern:

commands breaksw case pattern:

commands breaksw default:

commands breaksw endsw

每 一 个 模 式 将 与 test-string 相 匹 配 , 直 至 找 到 与 test-string 相 匹 配 的 模 式 为止 。 如 果 没 找 到 与 之 匹 配 的 模 式 , 缺 省 的 项 将 被 执 行 , 该 缺 省 项 由 关 键 词 开 头 , 且 是 可 选 的 , 你 也 可 以 没 有 该 项 , 但 是 , 告 诉 用 户 没 有 找 到 与 test-string 匹 配的 模 式 是 有 用 的 。

switch 控 制 结 构 通 常 被 用 来 实 现 菜 单 。 下 面 的 例 子 程 序 lschoice 要 求 用 户

输 入 以 不 同 方 式 列 出 当 前 目 录 下 的 文 件 。 必 须 注 意 , default 项 的 作 用 在 于 对 无法 找 到 匹 配 的 字 符 串 输 入 提 出 警 告 。

lschoice 脚 本 程 序 清 单 :

#

echo s. List Sizes

echo l. List All File Inforamtion echo c. List C Files

echo -n "Please enter choice: " set choice=$<

switch ($choice) case s:

ls -s breaksw case l:

ls -l breaksw case c:

ls *.c breaksw default:

echo Invaid Option

breaksw endsw

  • lschoice

s. List Sizes

l. List All File Inforamtion

c. List C Files

P lease enter choice: c io.c lib.c main.c

>

循 环 : while 和 foreach

TCSH Shell 中 有 一 组 循 环 控 制 结 构 , 这 些 循 环 控 制 结 构 允 许 你 多 次 重 复 执行 Linux 命 令 , 它 们 是 : while 、 foreach 及 repea t。 TCSH Shell 的 控 制 结 构 在表 16-7 中 列 出 。while 控 制 结 构 与 C 语 言 中 的 switch 语 句 类 似 ,与 TCSH Shell 中 的 if 控 制 结 构 一 样 , while 控 制 结 构 首 先 检 验 表 达 式 的 值 ; TCSH Shell 中 的foreach 控 制 结 构 与 BASH Shell 中 的 for 和 for-in 控 制 结 构 一 样 , 不 进 行 任 何检 验 , 它 仅 仅 逐 步 把 一 系 列 值 依 次 赋 值 给 指 定 的 变 量 。 在 这 方 面 , foreach 控 制结 构 与 其 它 程 序 设 计 语 言 中 的 相 关 语 句 有 很 大 不 同 。

while

while 控 制 结 构 用 来 重 复 执 行 Linux 命 令 。 一 个 while 循 环 以 关 键 词 while

开 头 , 然 后 紧 接 其 后 是 由 圆 括 号 括 起 来 的 表 达 式 , 以 关 键 词 end 结 束 while 循

环 。 while 循 环 控 制 结 构 的 句 法 如 下 :

while ( expression ) commands

end

我 们 可 以 用 while 循 环 控 制 结 构 及 switch 控 制 结 构 的 组 合 编 制 菜 单 驱 动 程序 。 注 意 下 面 的 例 子 包 含 菜 单 quit 选 项 , 该 菜 单 将 赋 值 no 给 变 量 again , 并 退出 循 环 。

lschoice 脚 本 程 序 清 单 :

#

set again=yes

while ($again == yes ) echo "1.List Sizes"

echo "2.List All File Information" echo "3.List C Files"

echo "4.Quit"

echo -n "Please enter choice: " set choice = $<

switch ($choice) case 1:

ls -s

breaksw case 2:

ls -l breaksw case 3:

ls *.c breaksw case 4:

set again = no echo Good-bye breaksw default:

echo Invalid Option endsw

end

>lschoice 1.List Sizes

  1. List All File Information

  2. List C Files 4.Quit

P lease enter choice: 3 main.c lib.c file.c 1.List Sizes

  1. List All File Information

  2. List C Files 4.Quit

P lease enter choice: 4 Good-bye

>

foreach

foreach 控 制 结 构 用 来 把 一 系 列 的 值 逐 步 赋 值 给 某 变 量 。 它与 BASH Shell 中 的 for-in 控 制 结 构 非 常 类 似 。 foreach 结 构 有 两 个 操 作 数 : 变 量 及 由 圆 括 号 括起 来 的 一 系 列 值 ( 组 成 一 列 表 ) , 该 列 表 中 的 每 项 都 将 被 赋 值 给 foreach 结 构里 的 变 量 。 与 while 控 制 结 构 一 样 , foreach 控 制 结 构 是 一 种 循 环 结 构 , 每 循 环一 次 , 列 表 中 下 一 项 将 赋 值 给 变 量 , 直 至 最 后 一 项 , 然 后 终 止 循 环 。 与 while 循 环 控 制 结 构 一 样 , foreach 控 制 结 构 的 循 环 体 以 关 键 词 end 结 尾 。 switch 控制 结 构 的 句 法 如 下 :

foreach variable ( list of values ) commands

end

在 下 面 的 例 子 脚 本 程 序 mylist 中 , 用 户 要 求 简 单 地 输 出 列 表 项 中 的 每 一 项与 当 前 的 日 期 。

mylist 脚 本 程 序 清 单 :

#

set tdate='date'+%D"

foreach grocery ( milk cookies apples cheese ) echo "$grocery $tdate"

end

$ mylist

m ilk 12/23/96 cookies 12/23/96

apples 12/23/96

cheese 12/23/96

$

foreach 循 环 控 制 结 构 在 管 理 文 件 时 非 常 有 用 。 在 foreach 控 制 结 构 中 , 你可 以 使 用 Shell 特 殊 字 符 来 生 成 由 一 系 列 文 件 名 组 成 的 列 表 , 该 列 表 中 的 每 一个 文 件 名 将 被 赋 值 给 foreach 控

制 结 构 中 的 变 量 。 例 如 星 号 ( “ * ” ) 将 生 成 由 所 有 文 件 名 及 目 录 组 成 的 列表 ; *.c 将 生 成 由 所 有 的 以 .c 为 扩 展 名 的 文 件 组 成 的 列 表 , 这 些 文 件 通 常 是 C 程 序 源 文 件 。 下 面 的 例 子 将 把 每 一 个 文 件 都 拷 贝 一 备 份 , 并 把 这 些 备 份 放 置 到名 为 sourcebak 的 目 录 下 : 模 式 *.c 生 成 由 一 系 列 文 件 名 组 成 的 列 表 , 列 表 中 的每 一 项 被 赋 值 给 foreach 循 环 控 制 结 构 体 中 的 变 量 。

cbackup 脚 本 文 件 清 单 :

#

foreach backfile (*.c)

cp $backfile sourcebak/$backfile echo $backfile

end

>cbackup io.c

lib.c main.c

没 有 指 定 列 表 项 的 值 的 foreach 控 制 结 构 将 把 命 令 行 参 数 作 为 其 列 表 项 。 此时 , 在 运 行 shell 文 件 时 在 命 令 行 上 指 定 的 参 数 将 成 为 列 表 中 的 项 , 并 将 把 这 每个 命 令 行 参 数 值 按 次 序 依 次 赋 值 给 foreach 控 制 结 构 中 的 变 量 。 第 一 次 循 环 时把 第 一 个 参 数 赋 值 给 foreach 循 环 控 制 结 构 变 量 , 第 二 次 循 环 时 把 第 二 个 参 数赋 值 给 foreach 循 环 控 制 结 构 变 量 , 依 次 类 推 。

在 下 面 的 脚 本 程 序 my listarg 中 , foreach 循 环 控 制 结 构 列 表 中 的 值 没 有 指定 , 但 foreach 控 制 结 构 将 连 续 把 命 令 行 中 的 参 数 赋 值 给 grocery 变 量 , 直 至最 后 一 个 参 数 , 然 后 结 束 循 环 。

mylistarg 脚 本 程 序 清 单 :

#

set date='date'+%D"

foreach grocery ( )

echo "$grocery $tdate" end

  • mylistarg milk cookies apples cheese m ilk12/23/96

cookies 12/23/96 apples 12/23/96 cheese 12/23/96

>

你 也 可 以 用 特 殊 参 数 变 量 argv [ * ] 来 明 确 地 把 命 令 行 参 数 作 为 foreach 循环 控 制 结 构 中 的 列 表 项 。 下 面 的 例 子 中 , 在 运 行 cbackuparg 时 , 在 命 令 行 上加 入 了 一 组 C 程 序 文 件 名 , 在 foreach 循 环 控 制 结 构 中 , argv [ *] 将 代 表 命 令行 上 所 有 的 输 入 参 数 , 每 个 参 数 将 被 依 次 赋 值 给 变 量 backfile 。 第 一 次 循 环 时

$backfile 等 同 于 $argv [ 1 ] , 第 二 次 循 环 时 $backfile 等 同 于 $arg v[ 2 ] 。

变 量 argnum 用 来 引 用 每 个 参 数 。 文 件 运 行 的 结 果 显 示 表 明 : foreach 循 环控 制 结 构 中 的 变 量 backfile 的 值 与 输 入 命 令 行 参 数 是 一 致 的 。

cbackuparg 脚 本 程 序 清 单 :

#

@argnum = 1

foreach backfile ( $arg v[ * ] )

cp $backfile sourcebak/$backfile echo "$backfile $arg v[ $argnum ] " @argnum = @argnum + 1

end

  • cbackuparg main.c lib.c io.c main.c main.c

lib.c lib.c io.c io.c

小 结

你 可 以 用 TCSH Shell 中 的 history 实 用 程 序 列 出 、 查 找 你 先 前 运 行 过 的 命令 , 你 甚 至 可 以 编 辑 这 些 命 令 , 然 后 运 行 这 些 编 辑 后 的 命 令 。 用 TCSH Shell 中 的 alias 命 令 , 你 可 以 给 一 个 命 令 取 别 名 , 这 个 别 名 可 以 是 一 个 命 令 甚 至 是 带参 数 的 该 命 令 本 身 。 在 TCSH Shell 中 , 有 一 组 可 开 启 、 关 闭 的 特 征 开 关 变 量 。常 见 的 特 征 开 关 变 量 有 : ignoreeo f、 noclobber 、 noglob 。 特 征 变 量 ignoreeof 可 以 防 止 意 外 退 出 ; noclobber 特 征 变 量 可 以 防 止 在 进 行 重 定 向 操 作 时 覆 盖 已经 存 在 的 文 件 ; noglob 特 征 变 量 可 把 一 些 特 殊 字 符 仅 当 作 普 通 字 符 处 理 。

与 BASH Shell 及 PDKSH Shell 一 样 , TCSH Shell 也 具 有 和 其 它 编 程 语 言一 样 的 编 程 能 力 。 你 可 以 定 义 变 量 并 给 这 些 变 量 赋 值 , 你 也 可 以 使 用 控 制 结 构去 实 现 循 环 与 条 件 控 制 。 在 脚 本 程 序 中 , 你 可 以 定 义 变 量 、 嵌 入 shell 命 令 、 设置 条 件 控 制 结 构 , 也 可 以 象 运 行 其 它 程 序 一 样 去 运 行 它 们 。

定 义 的 变 量 可 以 是 字 符 型 变 量 或 数 字 型 变 量 。 声 明 并 给 字 符 型 变 量 赋 值 时要 用 set 命 令 , 而 声 明 数 字 型 变 量 并 给 它 们 赋 值 时 要 用 @ 命 令 。 @ 命 令 允 许 你

用 复 杂 的 数 字 、 关 系 及 位 运 算 表 达 式 的 值 来 给 一 数 字 型 变 量 赋 值 。 你 也 可 以 定义 环 境 变 量 。 在 该 Shell 下 创 建 的 所 有 子 Shell 中 , 环 境 变 量 都 是 可 访 问 的 。 环境 变 量 的 定 义 与 赋 值 需 使 用 setenv 命 令 , 但 该 命 令 更 常 用 来 给 特 殊 环 境 变 量 赋值 。

在 TCSH Shell 中 , 循 环 与 条 件 控 制 结 构 与 其 它 程 序 设 计 语 言 的 循 环 与 条 件结 构 类 似 。 TCSH Shell 中 的 循 环 控 制 结 构 有 : while 与 foreach 控 制 结 构 , 条件 控 制 结 构 有 if 与 switch 。if 及 while 控 制 结 构 与 其 它 程 序 设 计 语 言 中 的 if 与 while 结 构 完 全 一 样 , 它 们 以 测 试 表 达 式 的 值 为 假 来 结 束 循 环 。 如 果 测 试 表 达 式 的 值为 真 , if 条 件 控 制 结 构 将 执 行 其 控 制 结 构 内 的 命 令 。 测 试 表 达 式 是 一 个 TCSH Shell 表 达 式 , 该 表 达 式 中 的 操 作 算 子 与 C 程 序 设 计 语 言 中 的 表 达 式 操 作 算 子类 似 。 在 TCSH Shell 的 表 达 式 中 可 以 有 许 多 赋 值 、 算 术 、 比 较 及 位 运 算 算 子 , 而 BASH Shell 及 PDKSH Shell 的 表 达 式 中 , 有 些 算 子 是 不 能 用 的 。 与 C 程 序设 计 一 样 , 当 表 达 式 的 值 为 非 0 时 , TCSH Shell 表 达 式 为 真 , 反 之 , 当 表 达 式的 值 为 0 时 , TCSH Shell 表 达 式 为 假 。

switch 控 制 结 构 是 if 结 构 的 一 种 受 限 形 式 。 switch 控 制 结 构 把 字 符 串 与 一组 可 能 的 模 式 ( pattern ) 相 比 较 , 如 果 找 到 与 字 符 串 匹 配 的 模 式 , 则 与 该 模 式相 关 联 的 一 组 操 作 将 被 执 行 。 switch 控 制 结 构 在 要 实 现 菜 单 ( 即 要 用 户 在 可 能的 几 个 选 项 中 作 出 选 择 ) 时 特 别 有 用 。 foreach 控 制 结 构 用 来 把 一 列 表 中 的 所 有项 依 次 赋 值 给 指 定 的 变 量 ,该 控 制 结 构 它 没 有 测 试 条 件 。列 表 中 的 项 可 以 由 Shell 特 殊 字 符 来 生 成 或 直 接 指 定 。 例 如 星 号 ( “ * ” ) 将 生 成 一 个 由 所 有 文 件 与 目 录名 组 成 的 列 表 ; 同 时 , 列 表 中 的 项 也 可 以 由 一 组 字 符 串 直 接 指 定 , 然 后 这 些 指定 的 字 符 串 将 依 次 赋 值 给 foreach 控 制 结 构 中 的 变 量 。 foreach 控 制 结 构 将 一 直

循 环 下 去 , 直 到 列 表 中 的 最 后 一 项 也 被 赋 值 完 为 止 。附 表 :

16-1 TCSH Shell history 实 用 程 序 命 令

事 件 引 用

功能

! event num

通 过 历 史 事 件 号 引 用 历 史 事 件

! characters

通 过 历 史 事 件 的 字 符 串 前 缀 引 用 历 史 事 件

! ?pattern?

通 过 模 式 来 查 询 历 史 事 件 列 表 中 的 事 件

! -event num

! num1-num2

通 过 历 史 事 件 号 偏 移 来 引 用 历 史 事 件

引 用 历 史 事 件 号 在 num1 与 num2 之 间 的 事 件

事 件 字 符 串 引 用

! event num:word num 引 用 事 件 号 为 num 的 历 史 事 件 中 的 特 定 单 词

( word )

! event num: ^ 引 用 事 件 号 为 num 的 历 史 事 件 中 的 第 一 个 参 数

( 第 二 个 单 词 )

!

event num:$

引 用 事 件 号 为 num

的 历 史 事 件 中 的 最 后 一 个 参

!

event num:^-$P

引 用 事 件 号 为

num

的 历 史 事 件 中 所 有 的 参 数

!

event num:*

引 用 事 件 号 为 num

的 历 史 事 件 中 所 有 的 参 数

事 件 编 辑 与 替 换

! event

num:s/pattern/newtext/

用 模 式 替 换 来 编 辑 一 历 史 事 件 。 用 来 定 位 历 史事 件 中 特 定 的 单 词

! event

num:sg/pattern/newtext/

! event

num:s/pattern/newtextp

用 模 式 来 替 换 历 史 事 件 中 所 有 匹 配禁 止 编 辑 后 历 史 事 件 的 执 行

表 16-2TCSH Shell 特 征 变 量

命 令 及 特 征 开 关 变 量 功能

set 与 unset 命 令 用 set 或 unset 命 令 来 打 开 或 关 闭 Shell 特征 变 量

$ set feature-variable

$ set noclobber 打 开 noclobber 特 征 变 量

$ unset noclobber 关闭 noclobber 特 征 变 量

echo 在 执 行 该 命 令 之 前 回 显 该 命 令 行

ingoreeof 禁 止 使 用 CTRL-D 退 出

noclobber 重 定 向 操 作 时 不 覆 盖 已 存 在 文 件

noglob 禁 止 文 件 名 中 特 殊 字 符 扩 展( 如 *、? 、~ 、及[ ])

notify 后 台 任 务 结 束 后 立 即 通 知 用 户

verbose 历 史 命 令 引 用 后 回 显 该 命 令

表 16-3TCSH Shell 特 殊 变 量

系 统 自 定 义 变 量 简 要 说 明

home HOME 用 户 主 目 录

LOGNAME 用 户 登 陆 名

Cwd 当 前 工 作 目 录

可 重 定 义 特 殊 变 量 简 要 说 明

shell SHELL 登 陆 Shell 目 录 路 径 及 程序名

path PATH 执 行 命 令 时 要 搜 索 的 目 录路 径 名 列 表

prompt 首 选 命 令 提 示 符

mail mail 实 用 程 序 在 收 到 消 息 时 要 检 查 的 邮 件 文 件名

用 户 级 定 义 变 量 简 要 说 明

cdpath 执行 cd 命 令 时 要 搜 索 的 子 目 录 路 径 名

history 历 史 事 件 列 表 中 要 保 存 的 历 史 事 件 数

savelist 为 下 次 登 陆 时 保 存 的 历 史 事 件 数 , 这 些 历 史 事件 被 保 存 在 文 件 .history 中

EXINIT Ex/Vi 编 辑 器 的 初 始 化 命 令

TERM 终 端 名

表 16-4 数 字 算 子

赋 值 算 子 功能 /说 明

= 赋 值 符

+= 与 表 达 式 相 加 , 然 后 赋 值

-= 与 表 达 式 相 减 , 然 后 赋 值

*= 与 表 达 式 相 乘 , 然 后 赋 值

/= 与 表 达 式 相 除 , 然 后 赋 值

% = 表 达 式 取 模 , 然 后 赋 值

++ 变 量 加 一

-- 变 量 减 一

  • 负 号 算 子

+ 加

* 乘

/ 除

% 取模

关 系 操 作 算 子

  • 大于

< 小于

>= 大 于 等 于

<= 小 于 等 于

!= 不 等 于

== 等于

16-5 表 达 式 操 作 算 子

字 符 串 比 较

功能 /简 要 说 明

==

字 符 串 相 等

!=

字 符 串 不 等

=~

字 符 串 与 模 式 比 较 , 测 试 两 者 是 否 相 等 , 模 式 可

以 是 任 何 常 规 表 达 式

!~

字 符 串 与 模 式 比 较 , 测 试 两 者 是 否 不 相 等 , 模 式

可 以 是 任 何 常 规 表 达 式

逻 辑 操 作 算 子

&&

逻 辑 与

||

逻 辑 或

!

逻 辑 非

文 件 测 试

-e

文 件 存 在

-r

文 件 是 只 读

-w

-x

文 件 可 以 被 修 改 ( 写 入 ) 文 件 可 以 被 执 行

-d

文 件 是 一 个 目 录 名

-f

文 件 是 一 个 二 进 制 文 件

-o

文 件 为 用 户 所 有

-z

文 件 为 空

16-6 TCSH Shell 命 令 与 变 量

Shell 命 令

功 能

echo

显 示 变 量 之 值 , -n 选 项 禁 止 输 出 至 新

eval

的 一 行

执 行 命 令 行

exec

在 当 前 进 程 中 执 行 命 令 ( 使 用 当 前 Shell

exit

而 不 生 成 新 的 子 Shell)

从 当 前 的 Shell 中 退 出

setenv va

r 使 变 量 var 可 以 被 每 个 新 创 建 的 子

printenv

Shell 存 取

显 示 所 有 环 境 变 量 的 值

set

给 变 量 赋 新 的 值 , 不 带 任 何 参 数 的 set

@

命 令 将 列 出 当 前 所 有 定 义 的 变 量

赋 值 与 数 字 表 达 式

shift

把 所 有 的 命 令 行 参 数 左 移 , 于 是 引 用

该 参 数 时 的 参 数 号 将 比 先 前 小 1 , 也

就 是 参 数 $3 将 赋 值 给 参 数 $2 , 依 次 类

unset

推 。 先 前 的 参 数 $1 将 丢 失

取 消 一 个 变 量 的 定 义

unsetenv

取 消 一 个 环 境 变 量 的 定 义

命 令 行 参 数

$argv [ 0 ]

$0

Linux 命 令 名

$argv [ n ] $n 从 1 开 始 的 第 n 个 命 令 行 参 数 , 你 可以 用 set 命 令 去 改 变 它 们 的 值

$argv [ *] $* 从 1 开 始 的 所 有 命 令 行 参 数 , 比 可 以用 set 命 令 去 改 变 它 们 的 值

$#argv $# 命 令 行 参 数 的 个 数

表 16-7TCSH Shell 控 制 结 构

条 件 控 制 结 构 :

if-then, esle , switch if ( expression ) then commands

endif

if ( expression ) then command

esle command endif

switch (string) case pattern: command breaksw default:

如 果 expression 为 真 , 其 后 的 命 令将 被 执 行 。 可 以 输 入 多 个 Linux 命 令

如 果 expression 为 真 , then 后 的 命令 将 被 执 行 。 如 果 expression 为 假 , else 后 的 命 令 将 被 执 行

可 以 使 你 在 多 个 命 令 之 中 作 出 选 择 的循 环 控 制 结 构 while 及 foreach

comman d

endsw

while (expression) command

end

foreach variable (arg-list) command

end

只 要 expression 的 值 为 真 ,

expression 后 的 命 令 将 永 远 被 执 行

arg-list 列 表 中 有 多 少 项 就 执 行 多 少 次该 循 环 。 每 执 行 一 次 循 环 , 列 表 中 一项 将 被 赋 值 给 变 量 variable 。 与Bourne Shell 中 的 for-in 控 制 结 构 类似