linux shell编程控制结构:expr、let、for、while、until、shift、if、case、break、continue、函数、select 学习笔记

SHELL编程一UNIX和Shell工具简介
什么是shell?

shell只是一个程序,它在系统中没有特权。因此,有多个不同风格shell共同存在原因——Bourne Shell,Korn Shell,C Shell。

在shell输入命令,先分析用户键入的每个命令,然后为执行程序作初始化。

Shell有自己的内部程序设计语言,这种语言是解释型的,shell用这种语言解释命令行的每一条语句,然后执行。

C等编译型语言,一般是先编译成可执行文件再执行。

1)正规表达式

. 匹配任意字符

ed files, ed 编辑命令

^contents 匹配行首符号

contents$ 匹配文件尾

[...] 匹配[]内的字符之一

* 配额0个或多个任意字符

\{...\}:x\{...\}匹配精确数目的字符串

\(...\): 保存匹配的字符串

2)cut

cut -cN file

cut -dchar -fN file

    char是分割符

   N 从第1 个开始数的第N 个字节、字符或域

     N- 从第N 个开始到所在行结束的所有字符、字节或域
     N-M 从第N 个开始到第M 个之间(包括第M 个)的所有字符、字节或域
     -M 从第1 个开始到第M 个之间(包括第M 个)的所有字符、字节或域
3)paste命令

paste file1 file2 file3 ,将三个文件的内容连接起来,直接在对应的每一行后连接而不是在第一个文件末尾连接

paste -d‘char’ file1,file2

       -d是 可选参数,文件连接的时候的默认分隔符是制表符,我们可以用-d来设定我们想要的字符,其中char的单引号最好是有,没大部分情况也是行的。

paste -d'char' -s file,-s告诉paste把同一个文件file的行用char连在一起

4)sed 用来编辑数据的程序,指的是流编辑器,与ed的区别是其不能用于交互

 sed 's/char1/char2/d' file,将file里面的每一个char1替换成char2,只有s的话只会将每行的第一个char2替换,加上g会将所有的char2替换

 sed -n '1,2p' file,选项-n表示没有显式要求的话不显示任意一行,显式指定用p命令来实现,该命令表示输出file的1-2行

 sed -n '/char/p' file,显示包含单词char的行

 sed ‘1,2d’file,删除file文件的1-2行

5)tr 过滤器tr用于转换来自标准输入的字符

 tr from-chars to-chars,from-chars 和to-chars都是一个或多个字符,输入的任意在from-chars的字符转换成to-chars中的字符

 tr a b < file, 将file中的a全部转成b

 tr '[a-z]' '[A-Z]' < file, 小写都换成大写

 tr -s ':' ' ' < file,假设有连续的多个:,假如没有-s,那么出来的结果将会是压缩成一个' '。

 tr -d ':' < file ,删除输入流中的:

6)grep 可以搜索一个或多个文件中特定的字符串模式

 grep char files

 grep -v char file 显示不包含char的行

 grep -l char * ,显示包含char的文件名

 grep -n char file, 显示行号

7)sort  对输入文件的每一行排序,默认升序

 -u 去掉重复行

 -r 降序排列

 -o,输出重定向,跟>很像,区别在于-o可以重定向为同一个文件,而>不行

 -n,按算术方法排序

8)uniq 查找并消除连续重复行

 uniq file1

 uniq file1 file2

 uniq file -d,输出连续重复的行

 uniq file -c,输出每行出现的次数


一、基础知识

Shell提供一个到UNIX系统的接口,它收集用户输入并根据输入执行程序,并显示程序的输出。有时被叫做命令解释器。

1、命令:简单命令、复杂命令(带参数)、复合命令(分号隔开,如:who; ll)。

2、Shell类型:Bourne Shell(包括sh, ksh, bash)和C Shell(包括csh, tcsh)。

3、模式:交互式和非交互式。

       交互式启动:$/bin/sh 退出:exit

       非交互式启动:$/bin/sh filename

4、初始化文件 /etc/profile

       使用的终端类型:TERM=vt100

       定位命令列表:PATH=/bin:/usr/bin

       定位命令帮助列表:MANPATH=/usr/man:/usr/share/man

5、执行 chmod a+x ./logins 例,内容为:

       #!/bin/sh               位于第一行,而在其他行时#开头为注

       who;ls;

6、文件操作:

       ls –aF;     cat filename;        wc filename; cp -i source destination;       

mv –i source destination;       rm files;

7、目录操作:

       pwd;      cd directory;          mkdir directory;            cp - r source destination;      

       mv source destination;          rmdir;            rm –r;

8、文件属性操作:

       符号链(相当于快捷方式或别名)创建:ln –s source destination

       管道

       chmod expression files; (r,w,x,o; 4读,2写,1执行)           

chown改变一个文件的所有权;  chown options user:group files

chgrp options group files

9、进程

       前台进程,后台进程。启动后台进程在命令后面添加&。

       前移后:ctrl+z. 后移前:fg. 使后台进程持续运行:nohup

       jobs(显示悬挂的及正在后台运行的进程)         ps(正在运行的所有进程)            kill

SHELL编程二
二、编程

1、变量

       定义:name=value (使用带空格的值时加引号)

       访问:$name

 例:FRUIT=apple    $echo $FRUIT(结果为apple)       $echo FRUIT(结果为FRUIT)

Bourne Shell只支持标量,Korn Shell中支持数组。

数组创建: name[index]=value          数组访问:${name[index]}

只读变量:readonly name

删除变量:unset name

局部变量(只在当前SHELL实例中存在),环境变量(SHELL任何子进程都能使用),SHELL变量(正确运行所必需,如PWD,PATH,HOME等)。

导出环境变量:export name

2、替换

(1)文件名替换通配符:*(匹配0个或多个)、?(匹配1个存在的任何字符)、[characters]。

匹配给出的字符,例ls test[0123456789].sql或ls test[0-9].sql 。匹配所有以字母或数字结尾的文件:ls *[a-z A-Z 0-9]。

否定一个集合:如列出所有除a开头的文件,ls [!a]*。

       (2)变量替换:

       ${parameter:-word}      若parameter为空或未设置,则用word代替,parameter值不变

       ${parameter:=word}      若parameter为空或未设置,则parameter设为值word

       ${parameter:?message}         若parameter为空或未设置,则message作为标准错误打印

       ${parameter:+word}      若parameter设置了,则用word代替,parameter值不变

       (3)命令和算术替换

              例:DATE=’date’                UP=’date; uptime’

                     foo:$((5+3)/2)

3、引用:关掉一个字符的特殊意义。

       三种方式:/(关掉某个),’(关掉全部),”(关掉部份)。

       例:echo Hello /; world        输出 Hello ; world

              echo ‘<125.**>;(update)’     输出<125.**>;(update)

              双引号未关掉:$用于参数替换,后引号 ’用于命令替换,”, /。

4、流控制

       (1)if语法:if  list1

                            then        list2

                            elif          list3

                            then       list4

                            else         list5

                            fi

                     其中elif和else可选。

       例:#!/bin/sh

              Fruit=apple

              F=b

              if $Fruit>$F;

              then echo $Fruit

              else echo $F

              fi

       使用test:test expression,可用文件测试、字符串比较、数字比较。

       (2)case语法:case  word  in

                                          pattern1)        list1  ;;

                                          Pattern2)        list2  ;;

                                   esac

                                   其中;;类似于break。

              例:#!/bin/sh

                     Fruit=apple

                     case “$Fruit” in

                                   apple) echo “I like apple.” ;;

                                   banana) echo “banana” ;;

                     esac

                     运行后输出I like apple.

       条件可以运前之前学习的进行组合出复杂表达式。

5、循环

       (1)while语法:while command

                                   do  list

                                   done

       例:输出1~10。

#!/bin/sh

              x=1

              while [ $x –le 10 ]

              do

                            echo $x

                            x=$(($x+1))

              done

              还可以进行嵌套。

       (2)until语法:until command

                                   do   list

                                   done

       (3)for语法:for name in word1 word2…wordN

                              do      list

                              done

例:输出1~10。

#!/bin/sh

              x=1

              for x  in 1 2 3 4 5 6 7 8 9 10

              do

                            echo $x

              done

       (4)select语法:select name in word1 word2…wordN

                                  do    list

                                  done

 

(5)break和continue。

6、参数(有些地方不明白)

       处理参数和选项采用如下方法:使用case语句手工处理参数和选项,使用getopts处理选项。

       (1)特殊变量

 

7、输入输出

       1)向终端输出:echo、printf(格式化输出,位于/usr/bin中)

 

       2)输出重定向:

“>”(把输出的内容重定向到指定的文件中)

“>>”(把输出的内容追加到指定的文件尾部)

tee(同时重定向到屏幕和文件)        :command | tee file

3)输入重定向

Command < file,例:Mail kony.sun@gmail.com < File_Exam

Command << delimiter

Document

Delimiter

4)读取用户输入

read name   直到用户输入回车为止。

5)管道

6)重定向到同一个文件

例:ll >file1 >&file2

8、函数

    1)创建和使用

    name( ) { list; } 例如:ls1( ) { ls –l; }

                        cd( ) { chdir ${1:-$HOME }; PSI=” ’pwd’ $” ; export PSI; }

    激活:$name

 

    2)函数间协同工作并共享数据

     略,P138

9、文本过滤器

    1)最常用的有:head, tail, grep, sort, uniq, tr。

    2)head格式:head [ -n lines ] files ,其中[ -n lines ]不写默认查看前10行,带的话指定前n行。

       组合使用,例检索5个最常访问的文件:ls –l ut /home/public_html | head -5

    3)tail格式:tail [ -n lines ] files ,其中[ -n lines ]不写默认查看后10行,带的话指定后n行。

    4)grep格式:grep word file ,例:grep creat test2.sql test.sql

                 grep -i word file ,不考虑大小写。

                

                 grep -v word file/dir ,不包括该单词的。

                 grep -n word file ,一起写出行号。

                 grep -l word dir ,只列出包含它的文件名。

    5)tr:将一个集合中的所有字符改变成别一个集合中的字符,也可用于删除字符集。

          tr  ‘set1’  ‘set2’

    6)sort:为输入文件占的行进行分类。

          例统计一个单词使用了多少次。

 

    7)uniq:打印出文件中所有的唯一行。若某行多次,只打一个。

            uniq filename

10、使用正规表达式过滤文本

1)command ‘script’ filenames

command是awk或sed,script是可以被awk或sed理解的命令清单,filenames表示命令所作用的文件清单。

2)正规表达式基本构造块包括:

普通字符:大小写字母、数字、字符。

元字符:.、*、[chars]、^、$、/。例:/a.c/匹配如a+c, a-c, abc行。

3)使用sed

/p打印,/d删除,/s/pattern1/pattern2将2代替1。

例:$sed ‘/0/.[0-9][0-9]$/p’ fruit_prices.txt ,告诉sed打印所有匹配模式/0/.[0-9][0-9]$的行。

11、使用awk过滤文本

编程语言。(见详解)

12、各种工具

1)eval命令:第二次处理命令行时使用。

2):命令:返回一个完成代码0,用于指示命令成功完成。

3)type命令:告诉用户一个指定命令的全路径。

4)sleep命令:暂停给定秒数,sleep n

5)find命令:检索,find start-dir options actions,例find / -nme alpha –print

6)xargs命令:从标准输入接收单词并将其提供给给定命令作为参数,cat filelist | xargs rm。

7)expr命令:执行简单整数算术运算,$expr 8/3

8)bc命令:不局限于整数的算术工具。

9)remsh/rsh/rcmd/remote命令:远程Shell

SHELL编程三高级主题
1、信号处理

    1)信号位于C语言头文件signal.h中。

2、调试

3、使用函数解决问题

1)创建库

创建Shell函数库就像创建Shell脚本,主要区别是库只包含函数,而脚本包含函数和主代码。

2)使用库中包含的函数:.file

3)常见函数:printERROR, printWARNING, pringUSAGE, promptRESPONSE, getSpaceFree, getSpaceUsed, getPID, getUID, toUpper, toLower, isSpaceAvailable, isUserRoot。

4、使用Shell脚本解决问题

5、脚本可移植性

1)判断unix版本:uname

   操作系统发行版本号:uname –rs

   硬件类型:uname –m

    主机名:uname –n

2)提高可移植性技巧:条件执行和抽取。

6、Shell编程疑难解答


shell编程实例:
1、expr计算整数变量值

格式 :expr arg

例子:计算(2+3)×4的值
1、分步计算,即先计算2+3,再对其和乘4
s=`expr 2 + 3`
expr $s \* 4
2、一步完成计算:
expr  `expr 2 + 3 `  \* 4
–说明:
运算符号和参数之间要有空格分开;
通配符号(*),在作为乘法运算符时要用\、“”、‘’符号修饰
–:expr 3 \* 2         expr 3 “*” 2       expr 3 ‘*’ 2
 `(反引号)与键盘上的~同一个键上的符号
 
[fsy@localhost ~]$ s=`expr 2 + 3`
[fsy@localhost ~]$ echo $s
5
[fsy@localhost ~]$ expr $s \* 4
20
[fsy@localhost ~]$ expr `expr 2 + 3` \* 4
20
[fsy@localhost ~]$ expr 2 \* 3
6
[fsy@localhost ~]$ expr 2 "*" 3
6
[fsy@localhost ~]$ expr 2 '*' 3
6
[fsy@localhost ~]$ expr 2 * 3
expr: 语法错误
[fsy@localhost ~]$
 
2、let命令
格式:let arg1 [arg2 ......]

说明:

与expr命令相比,let命令更简洁直观
 [ ]表示可以有多个参数,arg n (n=1,2…)
 运算符与操作数据之间不必用空格分开,但表达式与表达式之间必须要用空格分开
当运算符中有<、>、&、|等符号时,同样需要用引号(单引号、双引号)或者斜杠来修饰运算符
–例子:计算(2+3)×4的值
[fsy@localhost ~]$ let s=(2+3)*4
[fsy@localhost ~]$ echo $s
20
[fsy@localhost ~]$
3、for语句——坑爹的开始...... 和其他语言的for不同!

对一组参数进行一个操作
语法格式:
 
for 变量 in 列表
do
命令行(通常用到循环变量)
done
说明:
–“列表”为存储了一系列值的列表,随着循环的进行,变量从列表中的第一个值依次取到最后一个值;
–do和done之间的命令通常为根据变量进行处理的一系列命令,这些命令每次循环都执行一次;
–如果“ in 列表”部分省略掉,Bash则认为是“in $@”,即执行该程序时通过命令行传给程序的所有参数的列表。
例1、自定义列表

#!/bin/bash

for var in one two three four five
        do
                echo ------
                echo '$var is' $var
        done


 

运行输出:

------
$var is one
------
$var is two
------
$var is three
------
$var is four
------
$var is five


例2、以命令返回值作为列表

#!/bin/bash

for var in `ls`
        do
                echo -----
                echo $var
        done
           

运行输出:

-----
abb
-----
abc
-----
a.out
-----
a.sh
-----
b.sh
-----
hello.c
-----
scripts
-----


例3、命令行参数指定为列表中的数值

#!/bin/bash

for var
        do
                echo "It's $var"
        done


运行输出:

[fsy@localhost ~]$ sh c.sh a b c d
It's a
It's b
It's c
It's d


4、while语句

语法格式:
while      表达式 
do
命令行
done
说明:
–while循环中,只要条件为真,就执行do和done之间的循环命令;
–避免生成死循环。
 
例如:
#!/bin/bash

num=1
while [ $num -le 10 ]
do
echo -e "\t the num is $num"
let num=num+1
done


运行输出:

 the num is 1
 the num is 2
 the num is 3
 the num is 4
 the num is 5
 the num is 6
 the num is 7
 the num is 8
 the num is 9
 the num is 10


 

5、until语句

语法格式:
unitil      表达式 
    do
命令行
    done
说明:
–until循环中,只要条件不为真,就执行do和done之间的循环命令,或者说,在until循环中,一直执行do和done之间的循环命令,直到条件为真;
–避免生成死循环。
例:计算1到10的和

#!/bin/bash

sum=0
num=10

until test $num -eq 0
        do
                sum=`expr $sum + $num`
                num=`expr $num - 1`
        done
echo "sum = $sum"


运行输出
 
sum = 55

6、shift语句
shift语句:将变量的值依次向左传递,并形成一组新的参数值
–例:位置变量当前值为:1=file1 2= file2 3=file3
–        执行一次shift后为:1=file2 2=file3
还可以在shift命令中指定位置变量转移的次数
–shift n
 
例:
#!/bin/bash

while [ -n "$*" ]
        do
                echo $1 $2 $3 $4 $5 $6
                shift
        done

运行输出

[fsy@localhost scripts]$ sh b.sh 1 2 3 4 5 6 7
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7
4 5 6 7
5 6 7
6 7
7


7、if语句

if 语句的一般形式 :
if   条件表达式
then  #当条件为真时执行以下语句
         命令列表
else #当条件为假时执行以下语句
         命令列表
fi
  if的测试部分利用test命令实现,也可以利用一般命令执行成功与否来判断。如果命令正常结束,返回值为0,条件测试为真; 否则返回值不为0,条件测试为假
例:

#!/bin/bash

if test -f "$1"
        then
        echo "$1 is an ordinary file"
else
        echo "$1 is not an ordinary file"
fi


运行输出:

[fsy@localhost scripts]$ sh c.sh abb
abb is not an ordinary file
[fsy@localhost scripts]$ sh c.sh a.sh
a.sh is an ordinary file
[fsy@localhost scripts]$


8、case语句

   取值后面必须为单词in,每一个模式必须以右括号结束。取值可以为变量或常数。取值检测匹配的每一个模式,一旦模式匹配,其间所有命令开始执行直至;;。执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用*号捕获该值,再接受其他输入。
 
[注]
1.模式字符串中可以使用通配符
2.如果一个模式字符串中包含多个模式,那么各模式之间应以竖线(|)隔开,表各模式是“或”的关系,即只要给定字符串与其中一个模式相配,就会执行其后的命令列表。
3.各模式字符串应是唯一的,不应重复出现,并且要合理安排它们的出现顺序,例如,不应将“*”作为头一个模式字符串,因为“*”可以与任何字符串匹配,若第一个出现,就不会再检查其他模式了。
4.case语句以关键字case开头,以关键字esac结束。
5.case的退出(返回)值是整个结构中最后执行的命令的退出值。若没有执行任何命令,则退出值为0.
 

例:

#!/bin/bash

case $1 in
1)
        echo " you choice is 1";;
2)
        echo " your choice is 2";;
*)
        echo " your choice is others";;
esac

运行输出:

[fsy@localhost scripts]$ sh d.sh 1
 you choice is 1
[fsy@localhost scripts]$ sh d.sh 2
 your choice is 2
[fsy@localhost scripts]$ sh d.sh 3
 your choice is others


9、break与continue

–1、break:用于立即终止当前循环的执行,break命令可以使用户从循环体中退出来。
–语法:break[n] ,其中,n表示要跳出几层循环,默认值为1
–2、continue:跳过循环体中在其之后的语句,会返回到本循环层的开头,进行下一次循环。
–语法:continue[n],其中,n表示从包含continue语句的最内层循环体向外跳到第几层循环,默认值为1,循环层数是由内向外编号。
 

10、函数

  函数:由函数标题和函数体两部分组成。标题是函数名。函数体是函数内在的命令集合。标题名称必须唯一。变量均为全局变量,没有局部变量。
格式:
 [function] 函数名()             或   [function]函数名() {
                 {                                                         命令1
                  命令1                                                  …
                    …                                                       }
                  }
例:

#!/bin/bash

num=1
hello()
{
        echo "hello boy~ It's our $num meeting"
        let num=num+1
}

hello
hello
hello


运行输出

hello boy~ It's our 1 meeting
hello boy~ It's our 2 meeting
hello boy~ It's our 3 meeting


 

11、select语句

格式:

select 变量 in 列表
do
命令行(通常用到循环变量)
done
 

    制作一个选择表,在列表中选择一个选项执行命令行。如果选择的变量不在列表序列中,则返回一个空值。需要用break退出循环。

 

例子:

#!/bin/bash


echo "a is 5 ,b is 3. Please select your method: "

a=5
b=3

select var in "a+b" "a-b" "a*b" "a/b"
do
        break
done

case $var in
"a+b")
        echo 'a+b= '`expr $a + $b`;;
"a-b")
        echo 'a-b= '`expr $a - $b`;;
"a*b")
        echo 'a*b= '`expr $a \* $b`;;
"a/b")
        echo 'a/b= '`expr $a / $b`;;
*)
        echo "input error"
esac


运行输出:

[fsy@localhost scripts]$ sh e.sh
a is 5 ,b is 3. Please select your method:
1) a+b
2) a-b
3) a*b
4) a/b
#? 1
a+b= 8

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值