270 likes | 394 Views
上机环境. 上机环境 telnet 202.112. 97.50 用户名 : stu01-stu31 不同班的相同学号同学登入到同一用户 口令与用户名相同 , 不许修改口令 建立自己子目录 , 例如 : 侯涛 , 登录 stu17, 建立子目录 houtao 所有文件放到自己的目录 houtao 下 注册 shell 为 ksh ,执行 csh 启动 C-shell 设置终端类型 setenv TERM vt100, 然后才能使用 vi. 上机作业. 作业
E N D
上机环境 上机环境 telnet 202.112.97.50 用户名: stu01-stu31 不同班的相同学号同学登入到同一用户 口令与用户名相同,不许修改口令 建立自己子目录,例如: 侯涛,登录stu17,建立子目录houtao 所有文件放到自己的目录houtao下 注册shell为ksh,执行csh启动C-shell 设置终端类型setenv TERM vt100, 然后才能使用vi
上机作业 作业 编程实现myrm,功能与rm相同,实现 -i -r --三选项 感受shell的文件名替换,命令选项的处理,系统调用 相关系统调用 void perror (const char *s); int unlink(char *path); int rmdir(char *path); int stat (char *path, struct stat *buf); opendir/readdir/closedir 头文件: #include <sys/types.h> #include <sys/stat.h>
上机作业:举例 遍历当前目录下所有文件和子目录名myls.c #include <dirent.h> main() { DIR *dirp,*dp; dirp = opendir("."); while(dp=readdir(dirp)) printf("%s\n",dp->d_name); closedir(dirp); }
sh变量 存储的内容 字符串(对于数字串来说,不是二进制形式) 在执行过程中,其内容可以被修改 变量名:第一个字符必须为字母, 其余字符可以是字母,数字,下划线
shell变量的赋值和引用 引用时,在变量名前加$符,代表变量的内容 例1:$addr=20.1.1.254最左侧的$为sh命令提示符 $echo $addr引用addr,echo执行前,sh完成变量替换 20.1.1.254 例2:赋值时,等号右侧的字符串中含有特殊字符 $unit=”Shandong ICBC” $echo $unit Shandong ICBC 例3: 引用一个未定义的变量,变量值为空字符串 $echo My Computer Connected to $proto Networks My Computer Connected to Networks $proto=X.25 $echo My Computer Connected to $proto Networks My Computer Connected to X.25 Networks
命令echo 语法:echo arg1 arg2 arg3 ... 功能: 打印各个命令行参数,每两个之间用一个空格分开,最后打印一个换行符。 echo支持C语言字符串常数描述格式的转移和\c: \c打印完毕,不换行 \b退格 \n换行 \r回车 \t水平制表\\反斜线 \0nnn八进制描述的字符ASCII码 举例: echo Beijing China echo “Beijing China” echo ‘\065’ 打印5 echo \\0101 打印A echo “\r$cnt \c”
环境变量和局部变量 默认类型 所创建的shell变量,默认为局部变量 内部命令export 局部变量转换为环境变量,例如: export proto 局部变量和环境变量 在当前shell下启动的子进程只继承环境变量,不继承局部变量。子进程中对环境变量的修改,不影响父进程中的同名变量的值。 相关命令set/env 命令set会列出当前所有变量及其值(包括环境变量和局部变量) 命令env只列出环境变量及其值
环境变量:shell程序举例 例:$cat stat.report;chmod u+x stat.report echo My Computer Connected to $proto Networks $proto=X.25 $stat.report 启动一个子进程sh My Computer Connected to Networks $export proto $stat.report My Computer Connected to X.25 Networks
环境变量:C程序举例 main() { char *envstr; envstr = getenv(”proto”); if(envstr) printf(”Protocol is %s\n”,envstr); else printf(”Protocol is ??\n”); }
系统需要的环境变量 系统一登录成功后就由系统自动创建好一些环境变量,控制应用程序的运行。 HOME 用户主目录的名字 PATH 命令查找路径,与DOS不同的是,它不首先搜索当前目录 例:PATH=/bin:/usr/bin:/etc PATH=./:/bin:/usr/bin:/etc 先搜索当前目录 PATH=/:bin/usr/bin:/etc:./ 后搜索当前目录 PS1和PS2 (默认:PS1=”$” PS2=”>”) sh主提示符和副提示符。副提示符:当一个命令在一行内输不完需几行输入一个命令时,第2行及其它行用副提示符 TERM 终端类型,全屏幕操作的软件(如vi),使用它搜索终端库
shell替换 Shell的替换工作 命令替换/变量替换/文件名生成 sh先替换命令行,然后再执行相关命令 文件名生成 遵循文件通配符规则,按照字典序排列 如: ls *.c文件名替换后实际执行ls a.c x.c 变量替换 ls $HOME echo “My home is $HOME, Terminal is $TERM”
shell替换:命令替换 用反向单引号 $now= `date`以命令date 的stdout替换‘date‘ $./arg `date` 实际执行 ./arg Sun Dec 4 14:54:38 Beijing 2001 $frames=`expr 5 + 13` $echo $frames 18 $count=10 $count=`expr $Count + 1` $echo $count 11
sh内部变量:命令行参数 $0脚本文件本身的名字 $1 1号命令行参数 $# 命令行参数的个数 ”$*”为 ”$1 $2 $3 $4 ...” ”$@”为 ”$1” ”$2” ”$3” … $cat param echo $# echo ”Usage: $0 arg1 arg2 ...” arg ”$@” arg ”$*”
sh的特殊字符 空格,制表符 命令行参数的分隔符 回车 执行键入的命令 > < | 重定向与管道 (还有||) ; 用于一行内输入多个命令(还有;;) & 后台运行 (还有&&) $ 引用shell变量
sh的特殊字符(续) ` 反向单引号,用于命令替换 * [] ? 文件通配符 (echo ”*”与echo *不同) \ 取消后继字符的特殊作用(转义), 若后继字符为非特殊字符,则不起作用 ( ) 用于定义shell函数,以及定义命令表 分隔符 ( )><|;&等除了它们自身的特殊含义外还同时起到分隔符的作用(同空格)
sh的特殊字符:引号 双引号“ 除$和`外特殊字符的特殊含义被取消 特殊需要的转义:\” \$ \` 例:echo ”\A”显示\A echo \A显示A echo *与 echo “*” 单引号’ 对所括起的任何字符,不做特殊解释, 特殊字符的特殊含义被取消(特殊需要的转义:\’) 例: echo “My home dir is $HOME” echo ‘My home dir is $HOME’
条件 条件判定的依据 判定一条命令是否执行成功,判断方法:命令执行的返回码,0:TRUE(成功),非0:FALSE(失败) $ls -d xyz xyz $echo $?$?上一命令的返回码,shell自定义变量 0 $ls -d xyz1 xyz1: not found $echo $? 2 用管道线连接在一起的若干命令的执行返回码为最后一个命令执行的返回码
最简单的条件判断 用&&或||连结两个命令 命令1 && 命令2 若命令1执行成功(返回码为0)则执行命令2,否则不执行命令2 命令1 || 命令2 若命令1执行失败(返回码不为0)则执行命令2,否则不执行命令2 $ ls -d xdir >/dev/null && echo FOUND FOUND 若没有目录xdir $ls -d xdir >/dev/null 2>&1 ||echo No xdir No xdir
命令true与false /bin/true 返回码总为0 /bin/false 返回码总不为0
命令test与[:文件特性 命令/bin/[要求其最后一个命令行参数必须为] 除此之外/bin/[与/bin/test功能相同 不要将方括号理解成一个词法符号 如: 命令test -r /etc/motd 与 命令 [-r /etc/motd] 执行结果完全相同 文件特性检测 -f普通文件 -r可读 -d目录文件 -w可写 -s size>0 -x可执行 例: test -r /etc/motd && echo readable [ -r /etc/motd ] && echo readable
命令test:字符串和整数 字符串比较 -n sl sl串长度大于0 sl=s2 s1与s2串相等 s1!=s2 s1串与s2串不等 注意:等号和不等号两侧的空格不可少 [ -n ”$a” ] || echo a=NULL 注意:$a的引号test $# = 0 && echo ”No argument” 整数的比较 -eq= -ne ≠ -gt> -ge ≥ -lt< -le ≤ 例: test `ls | wc -l` -ge 100 && echo ”Too many files”
命令test:逻辑运算 逻辑运算 ! NOT(非) -o OR (或) -a AND (与) 例: [!-d $cmd -a -x $cmd] && $cmd 注意:必需的空格不可省略 $cat here echo ”count=$#” [ $#=2 ] && echo Here $here *.c count=9 Here
复合命令 • 在条件满足时,执行若干个命令,就需要使用{ }或者( ) • DIR=/usr/bin • pwd • [ -d $DIR ] && { • cd $DIR • echo ”Current Directory is `pwd`” • echo ”`ls | wc -l` files” • } • pwd • 上例的执行结果如下: • /usr/jiang • Current Directory is /usr/bin • 400 files • /usr/bin
复合命令:{ }与( ) {}与()的书写规则 (list)在子shell中执行命令表list { list;}在当前shell中执行命令表list 注意:在左花括号后面必须有一个空格。 {}与()的区别 如果将上例中的{} 改成(),那么执行结果如下: /usr/jiang Current Directory is /usr/bin 400 files /usr/jiang
复合命令:举例 在使用{}时,多行合并为一行时不要漏掉所必需的空格和分号,如: [ -f core ] && { echo ”rm core” rm core } 写成一行应当为 [ -f core ] && { echo ”rm core”;rm core;}
条件结构if 语法 if condition then list elif condition then list else list fi 其中if/then/elif/else/fi为关键字 当条件判断后需要两个或多个分支时,&&和||就不够了,这时应当用if结构
条件结构if:举例 $cat errmonitor LOGFILE=./errlog date>>$LOGFILE if test -w errfile then cat errfile>>$LOGFILE rm errfile else echo ”No error”>>$LOGFILE fi then行可以和它下面的cat行合并成一行。 但是,if行不可以和then行合并成一行。 将两行合并: 分号使得一行内可以输入多条命令。 if test -r errfile; then