Linux下的shel1与make 、 shell 1.1什么是shel1 ●用户与 Linux的接口 ●命令解释器 ●支持多用户 ●支持复杂的编程语言 ● Shell有很多种,如:csh,tcsh, pdksh,ash,sash,zsh,bash等。 Linux的缺省 Shell为 bash(Bourne Again Shell) 程序,并且在把需要与用户交互的程序放在前台运行。11,可以同时在后台运行多个应用 Shell是用户和操作系统之间最主要接口。通过Sh 通过在多条命令的序列中使用变量和流程控制, Shell可以作为一名复杂的编程语言 1.2转义字符和通配字符 ●转义字符( metacharacters)指的是在 Shell中有特殊含义的字符。 例如:键,可以自动补齐。 通配一个字符:"? 通配多个字符:"*” 1.3输入输出重定向 ●系统定义三个标准文件:标准输入( stdin)、标准输出( stdout)、标准错误输入( stderr) ●管道符:"",将前一个命令的输出转成下一个命令的输入。 ●过滤器( filters):用来接收标准输入,经过一定的转化,再写到标准输出。所以,过滤 器一般放在管道符中间
Linux 下的 shell 与 make 一、shell 1.1 什么是 shell ● 用户与 Linux 的接口 ● 命令解释器 ● 支持多用户 ● 支持复杂的编程语言 ● Shell 有很多种,如:csh,tcsh,pdksh,ash,sash,zsh,bash 等。Linux 的缺省 Shell 为 bash(Bourne Again Shell)。 Shell 是用户和操作系统之间最主要接口。通过 Shell,可以同时在后台运行多个应用 程序,并且在把需要与用户交互的程序放在前台运行。 通过在多条命令的序列中使用变量和流程控制,Shell 可以作为一名复杂的编程语言。 1.2 转义字符和通配字符 ● 转义字符(metacharacters)指的是在 Shell 中有特殊含义的字符。 例如: | ; ! ? * [ ] $ \ " ' ` ~ ( ) { } ^ #ls file[1-10].c #count=`ls –l | grep ‘^d’| wc –l` ● 通配字符(wildcards)是转义字符的子集,用来查找匹配文件名 例如:? * [] [-] [!] ● 使用键,可以自动补齐。 通配一个字符:"?" 通配多个字符:"*" 1.3 输入输出重定向 ● 系统定义三个标准文件:标准输入(stdin)、标准输出(stdout)、标准错误输入(stderr) ● 管道符:"|",将前一个命令的输出转成下一个命令的输入。 ● 过滤器(filters):用来接收标准输入,经过一定的转化,再写到标准输出。所以,过滤 器一般放在管道符中间
每个程序起动时,就有三个文件描述: STDIN(0), STDOUT(1), STDERR(2)。用""改变输出,用″2〉"改变错误输出,用">〉"来追加到已有的文件中 常用的过滤器如下: expand,sed,awk,fmt,tac,tr,grep,nl, tee命令接收标准输入并将数据输出到标准输出和一个文件内。 多条命令可以输入到一行中,并用”;"字符分隔。在一行命令后加”\"表示另起一行继续 输入,下一行的提示符变为">" printf(“\t”) 1.4Shel1变量 ● Shell变量( Variables)是程序用来保存数据用的 ● Shell特殊变量:系统定义了一些特殊的变量。如$HOME等。使用set命令查看当时系统 中定义的变量 系统定义的特殊变量有:$TERM(当前终端类型),$PATH(命令的搜索路径), SMANPATH (手册页存放的目录),$HOME(用户主目录), SLANG(当前使用语言),$PS1,$PS2(命令提 示符),SHEL(当前Shel1名) 在命令行上打入:变量名=变量值,可以定义变量。使用echo$变量名查看变量值。 使用 unset取消对变量的定义。 # hello=”123” 单引号表示忽略其中所有的转义字符,双引号表示忽略其中除了$\以外的其他的 转义字符。反斜线(表示忽略下一个转义字符 多条命令可以输入到一行中,并用”;"字符分隔。在一行命令后加”\"表示另起一行继续 输入,下一行的提示符变为 ● Shell系统变量 $?最近执行的命令返回的值 $s:本进程的进程号 :最近后台进程号 $#:shel自变量个数,$l表示第一个自变量 ●Shel1用户变量 # varname= value:赋值 # readonly varname:标记只读 # export varname:标记移出:变量可以被子进程继承 #setenv PATH=/home: /usr: /etc: /bin /usr/bin: (csh H) # varname=expr$ )varname+1:变量值增1#x=S[$x+1 #echo SPATH 1.5定制用户环境
每个程序起动时,就有三个文件描述:STDIN (0),STDOUT(1),STDERR(2)。用""改变输出,用"2>"改变错误输出,用">>"来追加到已有的文件中。 常用的过滤器如下:expand,sed,awk,fmt,tac,tr,grep,nl,pr。 tee 命令接收标准输入并将数据输出到标准输出和一个文件内。 多条命令可以输入到一行中,并用";"字符分隔。在一行命令后加"\"表示另起一行继续 输入,下一行的提示符变为">" printf(“\t”); 1.4 Shell 变量 ● Shell 变量(Variables)是程序用来保存数据用的。 ● Shell 特殊变量:系统定义了一些特殊的变量。如$HOME 等。使用 set 命令查看当时系统 中定义的变量。 系统定义的特殊变量有:$TERM(当前终端类型),$PATH(命令的搜索路径),$MANPATH (手册页存放的目录),$HOME(用户主目录),$LANG(当前使用语言),$PS1,$PS2(命令提 示符),$SHELL(当前 Shell 名)。 在命令行上打入:变量名=变量值,可以定义变量。使用 echo $变量名 查看变量值。 使用 unset 取消对变量的定义。 #hello=”123” 单引号表示忽略其中所有的转义字符,双引号表示忽略其中除了 $ ` \ 以外的其他的 转义字符。反斜线(\)表示忽略下一个转义字符。 多条命令可以输入到一行中,并用";"字符分隔。在一行命令后加"\"表示另起一行继续 输入,下一行的提示符变为">" ● Shell 系统变量 $?:最近执行的命令返回的值; $$:本进程的进程号 $!:最近后台进程号 $#:shell 自变量个数,$1 表示第一个自变量 ● Shell 用户变量 #varname=value :赋值 #readonly varname :标记只读 #export varname :标记移出:变量可以被子进程继承 #setenv PATH=/home:/usr:/etc:/bin:/usr/bin: (csh 中) #varname=` expr $varname + 1 ` :变量值增 1 #x=$[ $x + 1 ] #echo $PATH 1.5 定制用户环境
●用户在登录 Shell时,会依次执行一系列的脚本 ●使用 alias命令,可以定义一些别名。 ' -f 登录BASH时,用户将依次执行一系列的脚本:/etc/ profile, SHOME/. bash profile (如果没有,执行$HOME/.bash_ login,还没有,执行$HOME/. profile)。注销时,会自 动执行 SHOME/. bash logout 使用 redhat的用户,登录时除了这两个文件以外,还会自动执行$HOME/. bashrc, 这个文件又会再执行/etc/ bashrc 1.6条件控制 1)test命令 测试文件、变量的属性,表达式的值,或命令执行返回值。 test-d /usr >[d /usr test -f. bashrc >[-f bashrc test Scount -gt 0>[Scount -gt0] 2)if语句 if(expression) then command-list command-list fi 3)case语句 pattern2)command-list 4)逻辑运算符&&和‖ test-f myfile c & echo"file found if test-f myfile c ther echo“ file found” test-f myfilec l echo "file not found if test!-f myfile c the echo“ file not foun 1.7循环控制
● 用户在登录 Shell 时,会依次执行一系列的脚本。 ● 使用 alias 命令,可以定义一些别名。 Alias ‘rm –f’ rm 登录 BASH 时,用户将依次执行一系列的脚本:/etc/profile , $HOME/.bash_profile ( 如果没有,执行 $HOME/.bash_login ,还没有,执行 $HOME/.profile)。注销时,会自 动执行 $HOME/.bash_logout 。 使用 redhat 的用户,登录时除了这两个文件以外,还会自动执行 $HOME/.bashrc , 这个文件又会再执行 /etc/bashrc 1.6 条件控制 1)test 命令 测试文件、变量的属性,表达式的值,或命令执行返回值。 test –d /usr → [ -d /usr ] test –f .bashrc → [ -f .bashrc ] test $count –gt 0 → [ $count –gt 0 ] 2)if 语句 if (expression) then command-list else command-list fi 3)case 语句 case $var in pattern1) command-list ;; pattern2) command-list ;; … esac 4)逻辑运算符 && 和 || # test –f myfile.c && echo “file found” if test –f myfile.c then echo “file found” fi # test –f myfile.c | | echo “file not found” if test ! –f myfile.c then echo “file not found” fi 1.7 循环控制
1)for语句 for var in word-list command-I done for count in 1 2 3 echo SI for or va 2) while语句 while(expression) done #greeting=hello world hile test Si-le 100: do case Si in 0)echo“***率***少>fle$i *)echo Si>fileS i= expr Si+ 1 例 d命令的实现 case S# in 1)cat>>SI 2)cat$2 *)echo"usage: append [from] to #chmod +x myappend #myappend filel file2 18函数 functionname() command-list usage
1)for 语句 for var in word-list do command-list done for count in 1 2 3 do echo $I done for var do 2)while 语句 while (expression) do command-list done #greeting=’hello world’ i = 1 while test $i –le 100 ; do case $i in *0) echo “**********”>file$i ;; *) echo $i > file$i ;; esac i = ` expr $i + 1 ` done 例:append 命令的实现: case $# in 1) cat >> $1 ;; 2) cat > $2 ;; *) echo ‘usage: append [from] to ’;; esac #chmod +x myappend #myappend file1 file2 1.8 函数 functionname( ) { command-list } usage()
usage“from..to 注意:函数的使用就象可执行程序一样,但必须先定义,后使用。 1.9here文档 hee文档指在shll脚本中指定输入源,而不是来自文件或标准输入,其中的“<”是 here文档保留字。 mail cindy <<l@s happy birthday I love you 1.10she1l内部命令:不产生子进程 l)eval在 shell程序中,利用变量的值来构建命令 A=Is B='we-w 2)exc:转去执行exec后命令,不建立新进程,也不返回到当前的执行过程,相当于goto 语句 exec echo hello 3)read:从标准输入设备(键盘)读入一行,并把读入的字依次赋给各变量,所有剩余的 字赋给最后一个变量 at ead what ho‘ I repeat$what” 4)shit:使命令行参数向左移动一位,并使记录参数总数的变量$#减1 #cat shiftdemo while test S#I=0 echo $1 $2 $3 shift #shiftdemo a b c b 5)wait:等待当前进程所有子进程结束,若wat后跟参数n,则等待进程n结束 #cat waitdemo
{ echo “usage:…..$1” } usage “from … to “ 注意:函数的使用就象可执行程序一样,但必须先定义,后使用。 1.9 here 文档 here 文档指在 shell 脚本中指定输入源,而不是来自文件或标准输入,其中的“<<”是 here 文档保留字。 # mail cindy << !@$ happy birthday I love you !@$ 1.10 shell 内部命令:不产生子进程 1) eval:在 shell 程序中,利用变量的值来构建命令 A=ls B= ‘ | wc -w’ eval $A$B 2) exec:转去执行 exec 后命令,不建立新进程,也不返回到当前的执行过程,相当于 go to 语句。 #cat execdemo exec date echo hello 3) read:从标准输入设备(键盘)读入一行,并把读入的字依次赋给各变量,所有剩余的 字赋给最后一个变量。 #cat parrot echo “you say:\c” read what echo “I repeat:$what” 4) shift:使命令行参数向左移动一位,并使记录参数总数的变量$#减 1 #cat shiftdemo while test $# != 0 do echo $1 $2 $3 shift done #shiftdemo a b c a b c b c c 5)wait:等待当前进程所有子进程结束,若 wait 后跟参数 n,则等待进程 n 结束。 #cat waitdemo
echo“ This is a new file (sleep 5; date)& echo“ the file terminate” April2010:0826BJT2002-04-20 The file terminate 6)trap:中断处理命令 trap命令表中断信号表 #cat trapfile trap trap echo This is INT. 3 for I in /bin /bin/usr cho si done 下面程序实现scan:扫描当前目录下的每一个子目录,并执行用户提交的命令: then cd sd/Si while echo“si trap exit 2 f1 7)点命令 在bsh利用命令执行一个命令时,不创建子进程。(csh中用 source) 8)空命令:不做任何事情 1.11she1l程序实例 下面程序 dircm测试当前目录与指定目录是否含有相同文件数 if test S#-ne 1 then echo"Usage: dircm dirname exit 1 else if test I-d SI then echo"IS1\"is not a directory
echo “This is a new file” (sleep 5; date)& wait echo “the file terminate” 执行结果: This is a new file April 20 10:08:26 BJT 2002-04-20 The file terminate 6) trap:中断处理命令 trap 命令表 中断信号表 #cat trapfile trap echo ‘ This is INT 2’ 2 trap echo ‘ This is INT 3’ 3 for I in /bin /bin/usr do echo $I done 下面程序实现 scan:扫描当前目录下的每一个子目录,并执行用户提交的命令: d=`pwd` for i in * do if test –d $d/$i then cd $d/$i while echo “$i:” trap exit 2 read x do trap : 2 ; eval $x; done fi done 7)点命令 . 在 bsh 利用 . 命令执行一个命令时,不创建子进程。(csh 中用 source) 8)空命令:不做任何事情 1.11 shell 程序实例 下面程序 dircmp 测试当前目录与指定目录是否含有相同文件数 if test $# -ne 1 then echo “Usage:dircmp dirname” exit 1 else if test !-d $1 then echo “\”$1\” is not a directory” exit 1 else
his=ls -I that='ls-ISI grep M-I - if test Sthis -ne Sthat then echo"Current directory and i"\ do not match' echo "Current directory and"SIl have same num berof files #d “abc" is not a directory 1.12shel程序的执行方法: 1)Schmo utx dircm S/dircm/usr/bin 4)$. dircm(用点命令执行程序,不创建子进程) % 6 source dircm(csh中) 二、make 大型程序维护工具 make command line Makefile make All the files of the project Makefile或 makefile:告诉make维护一个大型程序,该做什么。 Makefile说明了组成程 序的各模块间的相互关系及更新模块时必须进行的动作,make按照这些说明自动地维护这 些模块 Netdefs h 头文件 Subs.c network. c 源文件 编译 network 目标文件 连接 可执行文件
this = `ls –l |grep ‘^-’ | wc –l ` that = `ls –l $1 |grep ‘^-’ | wc –l ` if test $this –ne $that then echo “Current directory and \”$1\” do not match” else echo “Current directory and \”$1\” have same number of files” fi fi fi #dircmp abc “abc” is not a directory 1.12 shell 程序的执行方法: 1) $chmod u+x dircmp $./dircmp /usr/bin 2) $sh dircmp 3) $sh < dircmp 4) $ . dircmp(用点命令执行程序,不创建子进程) %source dircmp(csh 中) 二、make 2. 1 make 大型程序维护工具 Makefile 或 makefile: 告诉 make 维护一个大型程序,该做什么。Makefile 说明了组成程 序的各模块间的相互关系及更新模块时必须进行的动作,make 按照这些说明自动地维护这 些模块。 Netdefs.h 头文件 Subrs.c network.c 源文件 编译 Subrs.o network.o 目标文件 连接 Network 可执行文件
在 makefile( Makefile中,自顶向下说明各模块之间的依赖关系及实现方 network: network network o: network. c netdefs h subs. o: subs. c net defs. h cc -c subs. c 其中(3)—(6)可以简化为:(隐含的规则) network o subrs, o: netdefs h #make -f makefile 2.2 makefile要点 (1)宏(变量) CC=gCC S(CC)test.c Sa: current target s: all prerequisites (2)后缀规则( suffix rules) S(CC)c S(CFLAGS)-o S@ S< (3)模式规则( pattern rules) .O:% S(CC)-c S(CFLAGS) -o S@ S< (4)通配符* objects: = S(patsubst %.c, %o, s(wi idcard * c)) foo: Sob jects cc -o foo S(ob jects) (5) phony target(哑/假目标):不对应实际的文件,只是一个目标 PHONY. clean#如果这行不加,若当前目录下有一个 clean文件,则 make clean没有动作 clean: 这是 phony targe rm*o temp
在 makefile(Makefile)中,自顶向下说明各模块之间的依赖关系及实现方法: network: network.o subrs.o (1) cc –o network network.o subrs.o (2) network.o: network.c netdefs.h (3) cc –c network.c (4) subrs.o: subrs.c netdefs.h (5) cc –c subrs.c (6) 其中(3)—(6)可以简化为:(隐含的规则) network.o subrs.o: netdefs.h #make #make network #make –f makefile 2.2 makefile 要点 (1) 宏(变量) CC=gcc $(CC) test.c $@: current target $<:first prerequisite $^:all prerequisites (2) 后缀规则(suffix rules) .c.o: $(CC) -c $(CFLAGS) -o $@ $< (3) 模式规则(pattern rules) %.o:%.c $(CC) -c $(CFLAGS) -o $@ $< (4) 通配符* objects = *.o objects := $(wildcard *.o) objects := $(patsubst %.c,%.o,$(wildcard *.c)) foo : $(objects) cc -o foo $(objects) (5) phony target(哑/假目标):不对应实际的文件,只是一个目标 .PHONY: clean #如果这行不加,若当前目录下有一个 clean 文件,则 make clean 没有动作 clean: #这是 phony target rm *.o temp
(6) include filename:嵌套 makefile,暂停当前 makefile,转而读取指定的 filename include filename:忽略找不到 filename时的错误 (7)控制语句:ifeg, ifhe
(6) include filename:嵌套 makefile,暂停当前 makefile,转而读取指定的 filename -include filename:忽略找不到 filename 时的错误 (7) 控制语句:ifeq, ifneq