C shell编程笔记


一. 简介
1. 脚本开头是#!/bin/csh或者#!/bin/tcsh
2. 脚本开始执行时会首先读取.cshrc(.tcshrc)文件,在脚本的第一行使用-f选项将不再执行#!
3. 脚本注释使用'#'
4. 使编写好的脚本可执行 chmod +x script_name
5. 脚本中使用变量的方法是$VARIABLE_NAME或者是${VARIABLE_NAME}.脚本中使用反斜杠\可以转义历史替换符'!'
6. 脚本中使用`command`可以执行命令,但是如果输出结果中有换行则会被替换为空格
7. 设置变量set variable_name = XXX, 取消变量 unset variable_name

二. 用户输入
1. 标准的读取用户输入的方式为: set input = $<
2. 如果输入包含空格分开的多个字符串,则使用:set input = "$<",否则input的值是第一个词,而$<为所有的输入数据
3. 可以将用户的输入数据转换为字符串数组,对于1和2中的输入方式,input和$input[1]是相同的。注意,C shell中数组下标是从1开始
4. 使用set input = ( $< ),可以将用户的输入转换为字符串数组,并使用$input[i]访问第i个元素

三. 算术运算
1. C shell只支持整数运算,使用符号'@'将计算结果赋给数值变量
2. C shell支持的算术运算符包含+,-,*,/,%,<<,>>.含义同C语言相同。此外还支持 ++, --, +=, *=等操作符.不过在linux中>>,<<支持的并不是很好
3. 算术运算表达式规则比较繁琐,比较简单的方法就是在每个元素中间都添加空格,例如:@ a = 3 + 4; @ a ++
4. 对于浮点数的算术运算可以使用bc或者awk,例如set sqrt2 = `ehco "scale=100; sqrt(2) | bc"`

四. 脚本运算
1. csh -x script_name,对每一行执行变量替换,显示,然后执行
2. csh -v script_name,原样显示脚本行,然后执行
3. csh -n script_name,解释命令,但不执行.
4. set echo,对每一行执行变量替换,显示,然后执行
5. set verbose,原样显示脚本行,然后执行
6. #!/bin/csh -xv 或者是 #!/bin/tcsh -xv,可以同时打开回显和详细功能.

五. 命令行参数
1. 两种参数形式,位置参量和argv
2. 位置参量,C shell脚本的参数数量没有限制。使用$i(i>1 && i <10) 或者${i}(i>10)访问第i个变量,$0表示脚本名,$*表示所有的位置参量
3. argv变量,argv变量的下标从1开始.argv不包含脚本明。使用$argv[i]访问第i个参数,$argv[*]表示所有参数,$argv也表示所有参数,$#argv表示参数的个数,$argv[$#argv]表示最后一个参数。

六. 条件结构和流控制
1. 比较和逻辑运算符: ==(等于),!=(不等于),>(大于),<(小于),>=(大于等于),<=(小于等于),=~(字符串匹配),!~(字符串不匹配),!(逻辑非),||(逻辑或),&&(逻辑与).其中&&和||的执行模式和C语言相同。
2. 运算符优先级从高到低分别为 (), ~, !, * / %, + -, << >>, >>= <<=, == !=, =~ !~, &, ^, |, && , ||
3. if语句格式:
    if ( 表达式 ) then
       命令1
       命令2
       ....
    endif
4. if-else语句格式:
    if ( 表达式 ) then
       命令1
       命令2
       ....
    else
       命令3
       命令4
       ....
    endif
5. if-else if 语句格式:
    if ( 表达式 ) then
       命令11
       命令12
       ....
    else if ( 表达式 ) then
       命令21
       命令22
       ....
    ...
    else
      命令n1
      命令n2
      ....
    endif
6. 简单if格式:
    if ( 表达式 ) 命令1
7. 调用exit可以退出脚本程序,eixt可以带有一个整型参数
8. 在条件表达式中对命令求值的办法是在外面再套一层花括号,例如 if { ( who | grep $1 >& /dev/null ) } then, 可以对上面的求值结果取反,方法为:
    if ! { ( who | grep $1 >& /dev/null ) } then
9. goto语句可以跳转到某个标号处,标号的定义和C语言一样。
10. C shell的内置选项对文件进行测试:
     -d 该文件是目录;  -e 该文件存在; -f 该文件是个普通文件; -o 该文件归当前用户所有; -r 用户可以读此文件; -w 用户可以写此文件;
     -x 用户可以执行此文件; -z 该文件长度为0;
     在if语句中的使用方法为 if ( -d fileName ) then ...
11. C shell的test命令与文件测试:
     -b 对象是块特殊文件; -c 对象是字符特殊文件; -d 对象存在且是目录; -f 对象存在且是普通文件; -g 对象的set-group-ID位被置1;
     -k 对象的sticky位被置1; -p 对象是管道文件; -r 对象可读; -s 对象存在且非空; -t n n是终端的文件描述符; 
     -u 对象的set-user-ID位被置1; -w 对象可写; -x 对象可执行;
     在if语句中的使用方法为if { -c file } then ...
12. 条件结构可以嵌套
13. TC shell的文件测试
     -b,-c,-d,-e,-f,-g,-k,-o,-p,-r,-t n,-w,-x,-z的含义同上。
     -l 对象是符号链接;  -L ??
14. 在TC shell中,可以将多个标识合并在一起例如 if ( -rwx file ) then...
15. 在TC shell中,也可以使用filetest命令也可以将多个标识合并在一起,例如: filetest -lrx /dev/fd
16. -A 文件最后访问时间,从UNIX EPOCH开始的秒数; -A: 同A,不过使用时间戳格式
     -M 文件最后修改时间,从UNIX EPOCH开始的秒数; -M:同M,不过使用时间戳格式
     -C inode节点最后修改时间,从UNIX EPOCH开始的秒数; -C:同C,不过使用时间戳格式
     -F 组合文件标识符,以设备:索引节点的形式表示;   -G 组ID号
     -G:组名称,如果组位置,则使用组ID号;  -L 符号链接指向的文件名称
     -N 链接数量; -P八进制表示的权限,最前面不带0; -P:八进制表示的权限,但是最前面带0
     -Pmode 等价于-P file & mode.假设对同组用户和其他用户可以,-P22 file将返回22.若仅对同组用户可写,则返回20.如果都不可写,则返回0
     -Mode:同PMode类似,但是最前面带0
     -U 用户ID号; -U:用户名,若用户名位置,则使用用户ID号
     -Z 以字节为单位的文件大小
17. switch语句的格式为:
     switch(变量)
       case 常量1:
         命令11
         命令12
         ....
         breaksw
       case 常量2:
         命令21
         命令22
         ....
         breaksw
       ...
       case 常量n:
         命令n1
         命令n2
         ....
         breaksw
       default:
         命令n1
         命令n2
         ....
         breaksw
    endsw
    常量处可以使用正则表达式来匹配变量。switch的语义和C语言中的switch语句相同。
18. Here菜单
    格式为:
    cat << EOF
    multiple
    line 
    sentences.
    EOF
    通常用来显示菜单和switch搭配使用。

七. 循环结构
1. C shell提供两种循环:foreach循环和while循环。如果要对项目清单中的每一项都做处理,应使用foreach循环。如果直到满足某个条件后才退出循环,应使用while循环。
2. foreach循环的格式:
    foreach 变量 (词表)
        命令
    end
3. while循环的格式为:
    while ( 条件表达式 )
      命令
    end
4. repeat命令格式为:
    repeat n 命令
    表示将命令执行n次
5. shift命令将argv数组向左移动,移出的词将不存在于词表中了,因此argv数组的长度也将减1. shift也可以移动数组,注意使用格式为shift arr_name,不是shift $arr_name
6. break命令,跳出循环
7. continue命令,继续从头开始执行循环

八. 中断处理
1. onintr 标号; 用户按下ctrl+c之后,程序将跳转到标号处开始执行
    onintr -;用户按下ctrl+c之后,对程序不起任何作用
2. C shell中能处理的信号只有ctrl+c产生的interruption信号

九. setuid脚本
1. 脚本中第一行为#!/bin/csh -feb
    f,fast,快速启动,不执行.cshrc
    e,如果有中断,程序立即退出
    b,次脚本设置了setuid
2. 然后修改脚本的权限,方法为:
    chmod 4755 script_name 或者
    chmod +srx script_name

十. 保存脚本
1. 修改环境变量,将脚本所在的目录放置到公共目录中,然后修改path环境变量,将此目录的路径添加到path中。

十一. 内置命令
alias, bg[%job], break,breaksw,case lablel:, cd [dir],chdir [dir], contine, default:, dirs [-l], echo [-n] list, eval command, exec command, exit [expr], fg [%job], foreach var (wordlist), goto label, hashstat, history [-hr][n], if (expr), else if(expr) then, jobs [-l], kill [-sig] [pid] [%job].., kill -l, limit [-h] [resource[max-use]], login[username|-p],logout,nice [+n|-n][command], nohup [command], notify[%job], onintr[-|label],popd[+n],pushd[+n|dir],rehash,repeat count command,set [var [= value]], setenv [var [word] ], shift [variable],source [-h] name, stop[%job]...,suspend,switch(string),time[command],umask[value],unalis pattern, unhash, unset pattern, unlimit [-h] [resource], unsetenv variable, wait, while (expr)

附A:技巧和注意
1. 使用$?来测试某个变量是否被设置,若设置,返回真;否则返回false.
2. $?promp可以用来测试prompt变量是否被设置.通过检测prompt变量可以用来判断当前是在交互模式下还是脚本中。
3. 使用!之类的单操作符时,应该注意后面有个空格
4. 在if语句中操作包含多个单词的变量时,变量要加双引号
5. 检查Unix命令执行成功的方法是判断status变量是否等于0.
6. 使用别名(alias)来创建自定义的错误诊断信息。例如,alias Usage 'echo "    Usage:$0 require fileName. \!*; exit 2"' 在调用Usage时,可以使用字符串参数,将被!*替换。例如:Usage "Please input file name.".输出信息为:"    Usage:checkfile require fileName. Please input file name.".在参数中也可以使用变量。
7. 在()中执行命令可以产生字符串数组,例如( `ls` )可以产生以当前目录所有文件名构成的字符串数组
8. 注意break和switch中的breaksw含义不同,breaksw表示跳出switch语句,而break表示跳出最近的一层循环语句
9. repeat n break可以跳出多重循环
10. PATH和path的区别:
     PATH是环境变量所有shell都能看到的统一值,而path是当前shell中设置的局部变量。设置PATH和path的语法是不同的:
     setenv PATH newpath1:newpath2:$PATH
     set path ( newpath1 newpath2 $path )
附B: 关于词表
1. 词表的创建方式有:
    ( li chao 123 )
    ( `ls` )
     ( *.c )  //当前目录中匹配的文件
    ( $* )
    ( $< ) 
2. 词表的一个例子为path环境变量,下例为词表长度的增加:
    set a = ( 1 2 3 )
    set b = ( $a 4)
    这时,b将变成( 1 2 3 4 )

你可能感兴趣的:(Unix系统和编程)