Chinaunix首页 | 论坛 | 博客
  • 博客访问: 795897
  • 博文数量: 455
  • 博客积分: 9776
  • 博客等级: 中将
  • 技术积分: 5870
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-19 23:23
文章分类

全部博文(455)

文章存档

2011年(455)

分类: LINUX

2011-04-25 22:31:23

C shell
本章介绍C shell,之所以如此命名,是因为它很多的编程结构与符号和C 编程语言
相似。其中包括以下内容:
● 功能概述
● 语法
● 变量
● 表达式
● 命令历史
● 作业控制
● 调用shell
● 内置的C shell 命令
要想得到有关C shell 的更多信息,可以阅读在参考文献中列出的《Using csh &tcsh》。
功能概述
C shell 具备以下功能:
● 输入输出重定向
● 用于文件名缩写的通配符(元字符)
● 定制用户环境的shell 变量
● 整数运算
● 访问以前的命令(命令历史)
● 命令名缩写(别名)
● 用于写shell 程序的内置命令集
● 作业控制
● 文件名完成(可选)
语法
本部分介绍了针对C shell 的很多符号。包括以下内容:
● 特殊文件
● 文件名元字符
● 引用
● 命令方式
● 重定向方式
特殊文件
~/.cshrc 在shell 调用每一个实例时执行。
~/.login 在.cshrc 执行之后由登录shell 执行。
~/.logout 在退出时由登录shell 执行

~/.history 来自以前的登录中存储的历史列表。
/etc/passwd ~name 缩写的主目录的来源(可能来自NIS 或NIS+)。
文件名元字符
元字符描述
* 匹配任何有0 个或多个字符的字符串
? 匹配任何单个字符
[abc...] 匹配被括起来的字符中的任何一个;可以用连字符指定一个范围(例如,a-z、A-Z、0-9)元字符描述
{abc,xxx,...} 扩展括号中的每一个由逗号分隔的字符串。这些字符串不一定匹配实际的文件名
~ 当前用户的主目录
~name 用户name 的主目录
示例
% ls new* 匹配new、new.1 等
% cat ch? 匹配ch9 等,但不匹配ch10
% vi [D-R]* 匹配文件名开头是大写D 到大写R 的文件
% ls {ch,app}? 先进行扩展,然后匹配ch1、ch2、app1、app2 等
% mv info{,.old} 扩展成mv info info.old
% cd ~tom 将目录修改为用户tom 的主目录
引用
引用可以禁止字符的特殊意义,使字符按其本来意思加以使用,下表中的字符在C
shell 中有特殊的意义。
字符意义
; 命令分隔符
& 后台执行
( ) 命令分组
| 管道
* ? [ ] ~ 文件名元字符
{ } 字符串扩展字符,通常不要求引用
< > & ! 重定向符号
! ^ 历史替代,快速替代
", \ 用于引用其他字符
` 命令替代
$ 变量替代
space tab newline 单词之间的间隔
下列的字符用于引用:
"" 位于"和"之间的所有的字符都按其字面意义加以采用,下面这些具有特殊意义
的字符除外:

$ 产生变量替代。
` 产生命令替代。
" 表示双引号的结束。
\ 转义下一个字符。
! 历史字符。
newline  换行字符。
,, 除!(历史)和另一个, 以及换行符之外,位于, 和, 之间的所有字符都按其字
面意义加以采用。
\ 在其后的字符会按字面意义采用。通常用于"" 中以转义"、$、` 和换行符。用
于,, 内可转义换行符。经常用来转义一个历史字符(通常是!)。
示例
% echo ,Single quotes "protect" double quotes,
Single quotes "protect" double quotes
% echo "Don,t double quotes protect single quotes too?"
Don't double quotes protect single quotes too?
% echo "You have `ls|wc -l` files in `pwd`"
You have 43 files in /home/bob
% echo The value of \$x is $x
The value of $x is 100
命令方式
cmd & 在后台执行cmd。
cmd1 ; cmd2 命令序列,在同一行执行多个命令。
(cmd1 ; cmd2) 子shell,将cmd1 和cmd2 视为一个命令组。
cmd1 | cmd2 管道,用cmd1 的输出作为cmd2 的输入。
cmd1 `cmd2` 命令替代,用cmd2 的输出作为cmd1 的参数。
cmd1 && cmd2 逻辑与关系,执行cmd1(如果cmd1 执行成功)后再执行cmd2。
这是一种短路操作,如果cmd1 没有成功执行,cmd2 将永远不能执行。

cmd1 || cmd2 逻辑或关系,执行cmd1 或(如果cmd1 执行失败)cmd2。这是
一个短路操作,如果cmd1 执行成功,cmd2 将永远不能执行。
示例
% nroff file > file.out & 后台格式化
% cd; ls 顺序执行
% (date; who; pwd) > logfile 重定向所有输出
% sort file | pr -3 | lp 先对文件排序,再分页输出,然后打印
% vi `grep -l ifdef *.c` 编辑grep 找到的文件
% egrep ,(yes|no), `cat list` 指定一个搜索文件列表
% grep XX file && lp file 如果包含了该模式,则打印文件
% grep XX file || echo XX not found 否则,回显一个错误消息
重定向方式
文件描述符名称一般缩写默认
0 标准输入stdin 键盘
1 标准输出stdout 终端
2 标准错误stderr 终端
重定向方式可以改变一般的输入源和输出目标,参见下面的内容。
简单重定向
cmd > file
将cmd 的输出发送到文件file 中(覆盖)。
cmd >! file
和前一个命令意义相同,另外,还会忽略noclobber 选项。
cmd >> file
将cmd 的输出发送到文件file 中(追加)。
cmd >>! file
和前一个命令意义相同,但写文件的时候忽略noclobber 选项。
cmd < file
cmd 从文件file 中获取输入 。
cmd << text
读取标准输入,直到遇到一个和text 相等的行(text 可以存储在一个shell 变量中)。
输入通常使用终端键入或存储在shell 程序中。使用这类语法的命令通常有
cat、echo、ex 和sed。如果文本text 被引起来(用任何shell 引用机制),则该
输入会按其原来的意思逐字地通过。
多重重定向
cmd >& file 将标准输出和标准错误发送到file 中。
cmd >&! file 和上条命令相同,但忽略noclobber 的设置。
cmd >>& file 将标准输出和标准错误添加到file 的结尾。
cmd >>&! file 和上条命令相同,只是在追加或创建file 时忽略noclobber 选
项。
cmd1 |& cmd2 标准错误和标准输出一起执行管道功能 。
(cmd > f1) >& f2 将标准输出发送到文件f1 中;将标准错误发送到文件f2 中。
cmd | tee files 将cmd 的输出发送到标准输出(通常是终端)和files 中(参见
第二章中tee 下面的示例)。
示例
% cat part1 > book
% cat part2 part3 >> book
% mail tim < report
% cc calc.c >& error_out
% cc newcalc.c >&! error_out
% grep Unix ch* |& pr
% (find / -print > filelist) >& no_access
% sed ,s/^/XX /g, << "END_ARCHIVE"
This is often how a shell archive is "wrapped"
bundling text for distribution. You would normally
run sed from a shell program, not from the command line.
"END_ARCHIVE"
XX This is often how a shell archive is "wrapped",
XX bundling text for distribution. You would normally
XX run sed from a shell program, not from the command line.

变量
本部分介绍以下内容:
● 变量替代
● 变量修饰符
● 预定义的shell 变量
● .cshrc 文件示例
● 环境变量
变量替代
在下列替代中,大括号({})是可选的,除非必须用它来将变量名与后面的字符分开。
${var} 变量var 的值。
${var[i]} 在var 的i 位置处选择1 个或几个单词。i 可能是一个单个的数,也
可能是范围m-n、范围-n(缺m 暗示为1)、范围m-(缺n 暗示其余
的所有单词)中的数,或者是*(选择所有单词)。i 也可以是扩展
成此类值之一的一个变量。
${#var} var 中单词的个数。
${#argv} 参数的个数。
$0 程序的名称(通常不会在交互式shell 中设定)。
${argv[n]} 命令行上单个的参数(位置参数)。 n =1~9。
${n} 与${argv[n]}作用相同。
${argv[*]} 命令行上所有的参数。
$* 与$argv[*]作用相同。
$argv[$#argv] 最后一个参数。
${?var} 如果设置了var,则返回1;否则返回0。
$$ 当前shell 的进程号;在创建具有惟一名字的临时文件时,作为文件
名的一部分是有用的。
$?0 如果知道输入文件名,则返回1;否则返回0。
$< 从标准输入中读一行。
示例
对第三到最后之间的参数(文件)进行排序,并且将输出存储到一个惟一的临时文件
中:sort $argv[3-]>tmp.$$
只有当shell 是交互式时处理.cshrc 命令(即必须设置prompt 变量):
if ($?prompt) then
set commands,
alias commands,
etc.
endif
变量修饰符
除$?var、$$、$?0 和$< 之外,前面进行变量替代时,后面都可能跟着下面的修饰
符之一。如果使用括号,修饰符在它的里面。
:r 返回变量的根。
:e 返回变量的扩展。
:h 返回变量的头。
:t 返回变量的尾。
:gr 返回所有的根。
:ge 返回所有的扩展。
:gh 返回所有的头。
:gt 返回所有的尾。
:q 将一个单词列表变量引起来,将其各部分分隔开。当变量中包含不应进行扩展
的文件名元字符时,该选项比较有用。
:x 将一个模式引起来,并将它扩展成单词列表。
使用路径名修饰符的示例
下表展示了有关下面变量路径名修饰符的用法:
set aa=(/progs/num.c /book/chap.ps)
变量部分格式输出结果
正常变量echo $aa /progs/num.c /book/chap.ps
第二个根echo $aa[2]:r /book/chap
第二个头echo $aa[2]:h /book
第二个尾echo $aa[2]:t chap.ps

变量部分格式输出结果
第二个扩展echo $aa[2]:e ps
根echo $aa:r /progs/num /book/chap.ps
全部根echo $aa:gr /progs/num /book/chap
头echo $aa:h /progs /book/chap.ps
全部头echo $aa:gh /progs /book
尾echo $aa:t num.c /book/chap.ps
全部尾echo $aa:gt num.c chap.ps
扩展echo $aa:e c /book/chap.ps
全部扩展echo $aa:ge c ps

使用引用修饰符的示例
% set a="[a-z]*" A="[A-Z]*"
% echo "$a" "$A"
[a-z]* [A-Z]*
% echo $a $A
at cc m4 Book Doc
% echo $a:x $A
[a-z]* Book Doc
% set d=($a:q $A:q)
% echo $d
at cc m4 Book Doc
% echo $d:q
[a-z]* [A-Z]*
% echo $d[1] +++ $d[2]
at cc m4 +++ Book Doc
% echo $d[1]:q
[a-z]*
预定义的shell 变量
变量可以按两种方式来设置,第一种方式是分配一个值:
set var=value
第二种方式是仅仅打开它:
set var
下表展示了变量的赋值是通过一个等号(该等号后是变量接受的值的类型)来完成
的,然后再对值进行描述。(注意,无论如何都不能对argv、cwd 或status 之类的
变量进行显式赋值。)对于那些只能打开或关闭的变量来说,该表也相应介绍了在设
置它们时所做的工作。C shell 会自动设置下面一些变量:argv、cwd、home、path、
promt、shell、status、term 和user。
变量描述
argv=(args) 传递给当前命令的参数列表,默认是()
cdpath=(dirs) 当给cd、popd 或pushd 定位参数时,轮流搜索的目录列表
cwd=dir 当前目录的完整路径名
echo 在执行前重新显示每个命令行,和csh -x 命令相同
fignore=(chars) 在完成文件名时要忽略的文件名后缀列表(参见filec)
filec 如果设置了它,当按下Escape 键的时候,在命令行上输入的部分文
件名可以扩展成其完整的名称。如果匹配不止一个文件名,则键入
EOF 会列出可能的完全文件名
hardpaths 告诉dirs要显示那些是一个符号链接的目录的实际路径名
histchars=ab 一个两字符的字符串,用来设置用于历史替代和快速替代中的字符
(默认是!^)
history=n 要存储到历史列表中的命令的个数
home=dir 用户的主目录,从HOME 中初始化。~ 字符是该值的缩写形式
ignoreeof 忽略来自终端的文件结束标记(EOF),阻止意外退出
mail=(n file) 每5分钟或(如果指定n)每n 秒钟对一个或多个文件进行新邮件检查
nobeep 对不明确的文件完整性操作不振铃
noclobber 不重定向输出到一个已存在的文件,用来防止对文件的意外毁坏
noglob 关闭文件名扩展,用于shell 脚本中
nonomatch 将文件名元字符当作字面上的字符来对待。例如,vi ch* 是创建新
文件ch* 而不是输出“No match”
notify 立刻通知已完成作业的用户,而不用等待下一个提示符
path=(dirs) 列出搜索执行命令的路径名。可用PATH 初始化。SVR4 默认为(./
usr/ucb/usr/bin)。在Solaris 上,默认路径为(/usr/bin.)。然后
标准启动脚本再将它修改为(/bin /usr/bin /usr/ucb/ 等等)

变量描述
prompt=,str, 提示用于交互式输入的字符串,默认是%
savehist=n 退出时存储在~/.history目录中的历史命令的个数,在下一次登录
时可以访问到它
shell=file 当前使用的shell 程序的路径名,默认是/bin/csh
status=n 最后命令的退出状态。成功时,内置命令返回0;若失败,则返回1
term=ID 终端类型的名称,和TERM 一样
time=,n%c, 如果命令执行时间超过n 个CPU秒数,则报告用户时间、系统时间、
消耗时间和CPU 占有率。支持可选的%c 标志来显示其他数据
user=name 用户的登录名称,在USER 中初始化
verbose 进行历史替代之后,显示一个命令,和命令csh -v 作用相同
.csbrc 文件示例
# 预定义的变量
set path=(~ ~/bin /usr/ucb /bin /usr/bin . )
set mail=(/var/mail/tom)
if ($?prompt) then # 为交互式使用而设置
set echo
set filec
set noclobber ignoreeof
set cdpath=(/usr/lib /var/spool/uucp)
# 现在可以键入cd 宏
# 代替cd /usr/lib/macros
set fignore=.o # 对filec 忽略目标文件
set history=100 savehist=25
set prompt=,tom \!% , # 包括历史号
set time=3
# MY VARIABLES
set man1="/usr/man/man1" # 允许我执行cd $man1、ls $man1
set a="[a-z]*" # 允许我执行vi $a
set A="[A-Z]*" # 或grep string $A
# ALIASES
alias c "clear; dirs" # 使用引号保护;或|
alias h "history | more"
alias j jobs -l
alias ls ls -sFC # 重新定义ls 命令
alias del ,mv \!* ~/tmp_dir, # rm 的安全替代
endif

环境变量
C shell 维护了一系列环境变量(environment variable),它们明确地区别于shell 变
量,并且不是C shell 的部分。shell 变量只是在当前shell 内部有意义,而环境变量
则会自动输出,从而使环境变量成为全局变量。例如,C shell 变量只在定义它们的
特定脚本中才是可访问的,而环境变量可以应用到任何shell 脚本、mail 实用程序或
用户调用的编辑器中。
可按下列方式给环境变量赋值:
setenv VAR value
按惯例,环境变量名都是大写的。你可以创建自己的环境变量,也可使用下面预定义
的环境变量。
这些环境变量有一些相应的C shell 变量,如下所示:
HOME
主目录,和home 作用相同。可以彼此无关地进行修改。
PATH
搜索命令的路径,和path作用相同。改变任意一个路径则会修改存储在另一个
中的值。
TERM
终端类型,和term 作用相同。改变term 可修改TERM,但反之则不行。
USER
用户名,和user 作用相同。改变user可修改USER,但反之则不行。
其他环境变量包括:
EXINIT
类似于在.exrc 启动文件中的字符串(例如,set ai),是一个ex 命令的字符
串。由vi 和ex 使用。
LOGNAME
USER 变量的另一个名字。
MAIL
拥有邮件的文件。由邮件程序使用。它与C shell 中只用于检查新邮件的mail变
量不一样。
PWD
当前目录,该值从cwd 拷贝而来。
SHELL
默认情况下未定义,一旦初始化到shell,两者是一样的。

命令历史
前面执行过的命令存储在一个历史列表中。C shell 可以让你访问该列表,从而可以
对命令进行校验,重复执行它们,或对命令修改后再执行。history 内置命令可显
示历史列表,预定义的变量histchars、history和savhist也可以影响历史机制。
访问历史列表涉及三件事情:
● 进行命令替代(用!和^)
● 进行参数替代(一个命令内的特定单词)
● 用修饰符提取或替换一个命令或单词的部分
命令替代
! 开始一个历史替代
!! 先前命令
!N 历史表中第N 条命令
!-N 从当前命令开始往后第N 条命令
!string 以string 开始的最近的命令
!?string? 包含了string 的最近的命令
!?string?% 包含了string 的最近命令参数
!$ 先前命令的最后一个参数
!!string 上一条命令,然后追加string
!N string 第N 条命令,然后追加string
!{s1}s2 以字符串s1 开始的最近的命令,然后追加字符串s2
^old^new^ 快速替代,在先前命令中将字符串old 改成new,执行修改后的命令
命令替代示例
事先假定下面的命令:
3% vi cprogs/01.c ch002 ch03
事件序号键入的命令执行的命令
4 ^00^0 vi cprogs/01.c ch02 ch03
5 nroff !* nroff cprogs/01.c ch02 ch03
6 nroff !$ nroff ch03
7 !vi vi cprogs/01.c ch02 ch03
8 !6 nroff ch03
9 !?01 vi cprogs/01.c ch02 ch03
10 !{nr}.new nroff ch03.new
11 !!|lp nroff ch03.new | lp
12 more !?pr?% more cprogs/01.c
单词替代
单词说明符允许从先前命令行中提取单个的单词。冒号可以放在任何单词说明符的前
面。在一个事件序号之后,除非是这里显示的,否则冒号是可选择的。
:0 命令名
:n 参数序号n
^ 第一个参数
$ 最后一个参数
:n-m 参数n 到m
-m 单词0 到m,和:0-m 相同
:n- 参数n 至最后一个的前一个
:n* 参数n 至最后一个,和n-$ 相同
* 所有的参数,和^-$ 或1-$ 相同
# 当前命令行直到这点,很少用
单词替代示例
假定有下列命令:
13% cat ch01 ch02 ch03 biblio back
事件序号键入的命令执行的命令
14 ls !13^ ls ch01
15 sort !13:* sort ch01 ch02 ch03 biblio back
16 lp !cat:3* lp ch03 biblio back
17 !cat:0-3 cat ch01 ch02 ch03
18 vi !-5:4 vi biblio

历史修饰符
可以通过一个或多个修饰符来修饰命令替代和单词替代:
输出、替代和引用
:p 只显示命令但不执行。
:s/old/new 用字符串new 替代old,只影响第一个实例。
:gs/old/new 用字符串new 替代old,适用于所有的实例。
:& 重复先前的替代(:s 或^ 命令),只影响第一个实例。
:g& 重复先前的替代,适用于所有实例。
:q 将一个单词列表引起来。
:x 将分隔的单词引起来。
截取
:r 提取第一个可用的路径名的根。
:gr 提取所有的路径名的根。
:e 提取第一个可用的路径名的扩展名。
:ge 提取所有的扩展名。
:h 提取第一个可用的路径名的头。
:gh 提取所有路径名的头。
:t 提取第一个可用的路径名的尾。
:gt 提取所有路径名的尾。
历史修饰符的示例
以“单词替代示例”中的第17 条命令为例:
17% cat ch01 ch02 ch03
事件# 键入的命令执行的命令
19 !17:s/ch/CH/ cat CH01 ch02 ch03
20 !:g& cat CH01 CH02 CH03
21 !more:p more cprogs/01.c(只显示)
22 cd !$:h cd cprogs
23 vi !mo:t vi 01.c
24 grep stdio !$ grep stdio 01.c
25 ^stdio^include stdio^:q grep"include stdio" 01.c
26 nroff !21:t:p nroff 01.c(是我需要的吗?)
27 !! nroff 01.c(执行它)

作业控制
作业控制使用户可以将前台作业放到后台,将后台作业转到前台,或挂起(暂时停
止)正在运行的作业。C shell 对作业控制提供了下面的命令。要想获得这些命令的
更多信息,参见本章后面的“内置的C shell 命令”。
bg 将一个作业放至后台。
fg 将一个作业放至前台。
jobs
列出活动的作业。
kill
终止一个作业。
notify
当一个后台作业完成时通知。
stop
挂起一个后台作业。
CTRL-Z
挂起一个前台作业。
很多作业控制命令采用jobID 作为参数。可以按以下方式指定参数:
%n 作业号n
%s 作业的命令行是以字符串s 开始的
%?s 作业的命令行中包含字符串s
%% 当前作业
% 当前作业(和上面相同)
%+ 当前作业(和上面相同)
%- 先前的作业

阅读(1182) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~