400 likes | 820 Views
shell 的基本功能. 命令的解释执行 环境变量的设置 输入 / 输出重定向 shell 程序设计. bash 的初始化过程. 1.bash 检查文件 /etc/profile 是否存在 . 如果存在 , bash 则读取该文件 , 初始化环境变量 ; 否则跳过 . 2.bash 检查用户主目录下的文件 .bash_profile 是否存在 . 如果存在 ,bash 则读取该文件 ; 否则跳过 . 3.bash 检查用户主目录下的文件 .bash_login 是否存在 . 如果存在 ,bash 则读取该文件 ; 否则跳过 .
E N D
shell的基本功能 • 命令的解释执行 • 环境变量的设置 • 输入/输出重定向 • shell程序设计
bash的初始化过程 • 1.bash检查文件/etc/profile是否存在.如果存在, bash则读取该文件,初始化环境变量; 否则跳过. • 2.bash检查用户主目录下的文件.bash_profile是否存在.如果存在,bash则读取该文件;否则跳过. • 3.bash检查用户主目录下的文件.bash_login是否存在.如果存在,bash则读取该文件;否则跳过. • 2.bash检查用户主目录下的文件. profile是否存在.如果存在,bash则读取该文件;否则跳过. 这些步骤都结束完后,就显示默认的提示符$.
输入/输出重定向: UNIX下流的概念 Unix/Linux系统中,文件的组织方式是按字节进行的,文件之间和设备之间的信息传递是按字节流进行的,所以信息流的概念在系统管理中很重要。正因为文件被看成字符流,Unix类系统对文件后缀名没有强制要求,后缀名可以是任意的。 在系统内部,对用户文件的操作被转换为对文件描述符(fd)的操作,在执行输入输出命令时,Linux系统把输入/输出文件与信息流的概念对应起来。 • 注:用一个整数来代表所打开的文件,这个整数就是文件描述符。
输入/输出重定向: UNIX下流的概念 Linux自动为每条执行的命令(进程)打开三个文件,分别用于读取输入数据、发送输出数据和错误信息,这三个文件分别叫标准输入(stdin)、标准输出(stdout)和标准错误文件(stderr) • 信息流的标准定义: • 标准输入流(stdin): 文件描述符0, 默认为键盘. • 标准输出流(stdout): 文件描述符1, 默认为显示器. • 标准错误流(stderr): 文件描述符2, 默认为显示器.
输入/输出重定向 输入输出重定向就是对系统信息流标准定义的修改 • 输入重定向< 例: prog < infile • 输出重定向> ,>> 例: pwd > outfile ls –l >> file1 例:$ prog < infile > outfile • 错误流重定向 >& 例: gcc hello.c >& log
管道线(pipeline)的概念 • 在命令中利用管道线(|)将命令隔开,实现将一个程序或命令的输出作为另一个程序或命令的输入. • 例: $ ls -l | wc -l $ ls –l /dev | grep fd $ cat file | grep hello | wc -l • 下列字符可作命令表的分隔符 • ; 或 Enter • &&:若前一命令执行成功,则执行后一命令 • ||:若前一命令执行失败,则执行后一命令 如果不用管道线,该如何实现这一功能?
例: write zhang < letter || mail zhang < letter • 例: mail zhang < letter && rm letter • 三通道命令tee实现一个数据流向多个输出分流 • ps –ef | tee progm.ps
环境变量的设置 环境变量是系统预定义的一些变量,如PATH,LOGNAME 等变量,例如: echo $PATH • 查阅命令env • 相关文件: /etc/profile, ~/.bash_profile , ~/.bash_login ~/.profile < >
Shell Programming shell程序: 一种解释执行的脚本(script)语言,类似于DOS 下的.bat文件,但功能更强. shell是按行解释执行的,注释在行首加#,习惯文件的第一行以”#!/bin/sh”开头,指明使用哪种解释器. 执行方式(三种): • $ sh < file.sh • $ sh file.sh • 首先修改shell程序的权限为用户可执行,如: $ chmod 755 file.sh 然后在命令行下直接输入: $./file.sh (未打通路径,若打通路径,./ 不需要)
shell的变量通常只有字符类型,在shell编程中也会出现一些数值计算的量,但它们也是基于字符类型完成的。shell的变量通常只有字符类型,在shell编程中也会出现一些数值计算的量,但它们也是基于字符类型完成的。 变量的赋值 . 例:UNIX=SystemV 或 UNIX=“SystemV OS” 变量的引用:在变量名前加$,如 $UNIX 或 ${UNIX} ${UNIX}tm 打通路径: $ PATH=$PATH:$HOME //$HOME代表需要添加到路径变量中的目录名 shell变量的使用
不同的引号对shell变量产生不同的效果. 1)单引号’ ’:shell将单引号中的内容看成纯粹的字符串,如: $ file=report $ echo ’ The time is `date`,the file is $file ’ 结果: The time is `date`,the file is $file 2)双引号” ”:shell对双引号中的特殊字符进行解释,如: $ echo “ The time is `date`,the file is $file ” 3)反引号` `:对反引号中的内容作为shell命令执行,如: $ TT=`date` $ echo $TT shell变量的使用
变量的作用域 shell变量也有局部定义和全局定义之分。不做特殊说明的变量均是局部变量,只在为它赋值的shell进程中起作用。要是变量在多个进程中都能起作用,通过export命令使其变为全局变量. 见书本71页例子 shell变量的使用
命令的位置变量 在shell中命令的位置变量类似于C语言中argc和argv参数的功能,它们主要对命令行中各个参数的位置进行描述。记住$#, $?, $$, $!的定义 $# 位置参数的个数 $? 为前一命令返回的状态值(0为正常) $$ 当前shell进程的pid值 $! 最近访问的后台进程的pid值 $* 用单字符串显示传递参数 shell变量的使用
例echoarg.sh内容如下: echo $# for VAR in $* do echo $VAR done 运行:$echoarg.sh first second third $0 $1 $2 $3 结果:3 first second third shell变量的使用
变量的替换 例:$echo “the CDPATH is $ CDPATH” 当$CDPATH未被赋值时,显示 the CDPATH is 容易让用户产生困惑.可使用: ${var:-word} ${var:=word} ${var:+word} 可将上例改为: $ echo “the CDPATH is $ {CDPATH:-Undefined}” 则显示: the CDPATH is Undefined shell变量的使用
格式: test expre 或 [expre] 当表达式的值为真时,test命令返回真值0,否则返回假值非0. 对文件特性的测试: test –[dfrwxs] file 对字符串内容的测试: 建议访问变量使用”$var”的形式 对整数的测试 例:x1=“005”, x2=5, 注意: $test “$x1” = “$x2” 和 $test “$x1” -eq “$x2” 的区别 test命令的使用
if语句 (1) 无分支条件语句:if then (2)二分支条件语句:if then else (3)多分支条件语句:if then elif 条件控制语句 < >
格式: if [condition] then commands fi 例:if [$# = 1] then cp $1 $HOME/user1 fi vi $1 exit 0 无分支条件语句
格式: if [condition] then true-commands else false-commands fi P77 例5.5 二分支条件语句
格式: if [condition_1] then commands_1 elif [condition_2] then commands_2 elif [condition_3] then commands_3 ……. else commands_n fi 多分支条件语句
例5.7: #!/bin/sh if [$# -lt 3] then echo “usage: `basename $0` arg1 arg2 arg3” >& 2 exit 1 fi echo “arg1:$1” echo “arg2:$2” echo “arg3:$3” 分支条件语句
例5.8:testdir #!/bin/sh DIREC=$1 if [-z `ls –a $DIREC`] then echo “$DIREC is indeed empty” else echo “$DIREC is not empty” fi 运行时可输入: $ testdir /home/user1 例5.9自己看 分支条件语句
case语句: case in 结构 case word in pattern-1) pat1-list1;; pattern-2) pat2-list2;; …… *) default-list;; esac 条件控制语句 < >
例5.10: case $# in 1) cat >> $1;; 2) cat >> $2 < $1;; *) echo “usage: append.sh”;; esac 条件控制语句
例5.11: #!/bin/sh hour=`date+%H` case $hour in 0[1-9] | 1[01]) echo “Good morning!”;; 1[234567]) echo “Good afternoon!”;; *) echo “Good evening!”;; esac 例5.12: 条件控制语句
for循环: for in done结构 while循环: while do done结构 until循环: until do done 循环语句 < >
for循环: for in done结构 for variable in list-of-values do commands …… last-command done 循环语句 < >
例5.13: #!/bin/sh cd $HOME for dir in cc work do echo “….in $dir” cd $dir for file in *.[c] do ls –l $file done cd .. done 循环语句
while循环: while - do - done结构 只要循环条件为真就继续循环下去。 while [condition] do commands …… last-command done 例5.14 循环语句 < >
until循环: until - do - done结构 只要循环条件为假(非0值)就继续循环下去。 until [condition] do commands …… last-command done 另外,和C语言一样,break和continue语句也可以使用。 循环语句 < >
例5.15 uon until who | grep “$1” > /dev/null do sleep 30 done echo “07\07 $1 is logged on.” exit 0 运行: $ uon lili& 循环语句
expr是对shell变量进行算术运算的操作.例: $ count=0 $ count=$count+1 $ echo $count 显示为0+1 $ count=`expr $count+1` $ echo $count 显示为1 expr命令
在程序中显示错误信息 echo “usage: ``basename $0` arg1 arg2” >&2 将不必要的信息送入系统垃圾文件/dev/null (黑洞)中 例5.17 #!/bin/sh if cp myfile myfile.bak > /dev/null 2>& 1 then echo “good copy” else echo “ `basename $0`:error could not copy the files” >& 2 fi shell编程中常用的其他语句
在程序运行中读取标准输入流信息 read [word1] [word2]…[rest] 注意:read语句每次接受输入以换行(回车)结束,将输入按照IFS(默认为空格,Tab,回车)定义的分隔符分成不同的域。见例5.18 shell编程中常用的其他语句
例5.18 read_test #!/bin/sh echo ”give me a long sentence:” read word1 word2 rest echo –e “$word1\n $word2\n $rest” echo ”end of my act.” 运行后输入:let’s test the read command. 输出: let’s test the read command. end of my act shell编程中常用的其他语句
交互式调试 利用多窗口多进程边调试、边编辑 用shell程序提供的跟踪功能进行调试 -v –x选项 shell程序的调试方法 < >
假设score.txt文件中保存两个班级的同学的数学成绩,请编写一个shell程序计算每个班级的学生人数和平均分。score.txt内容如下:假设score.txt文件中保存两个班级的同学的数学成绩,请编写一个shell程序计算每个班级的学生人数和平均分。score.txt内容如下: wangpin:class1:87 wubo:class2:96 zhanghua:class1:65 xiaonong:class2:88 jiangbo:class2:93 …… shell程序举例
#!/bin/sh SCORE1=0 SCORE2=0 NUMBER1=0 NUMBER2=0 SAVEDIFS=$IFS IFS=: INFILE=score.txt shell程序举例
while read NAME CLASS SCORE do case $CLASS in class1) NUMBER1=`expr $NUMBER1 + 1 ` SCORE1=`expr $SCORE1 + $SCORE ` ;; class2) NUMBER2=`expr $NUMBER2 + 1 ` SCORE2=`expr $SCORE2 + $SCORE ` ;; *) ;; esac done < $INFILE shell程序举例
SCORE1=$(echo "scale=2; $SCORE1 / $NUMBER1 " | bc ) SCORE2=$(echo "scale=2; $SCORE2 / $NUMBER2 " | bc ) echo " class student number average score " echo "-----------------------------------------" echo " 1 $NUMBER1 $SCORE1 " echo " 2 $NUMBER2 $SCORE2 " shell程序举例