一、Linux程序分类:

1.守护进程(Daemon):开机自动启动

常见linux后台守护进程列举:

amd:NFS守侯进程

apmd:高级电源治理

Arpwatch:记录日志并构建一个在LAN接口上看到的以太网地址和ip地址对数据库

Autofs:自动安装治理进程automount,与NFS相关,依靠于NIS

crond:linux下的计划任务

Dhcpd:启动一个DHCP(动态IP地址分配)服务器

Httpd:WEB服务器

Inetd:支持多种网络服务的核心守候程序

Lpd:打印服务器

named:DNS服务器

netfs:安装NFS、Samba和NetWare网络文件系统

portmap:RPC portmap治理器,与inetd类似,它治理基于RPC服务的连接

routed:路由守候进程,使用动态RIP路由选择协议

sendmail:邮件服务器sendmail

smb:Samba文件共享/打印服务

snmpd:本地简单网络治理候进程

squid:激活代理服务器squid

syslog:一个让系统引导时起动syslog和klogd系统日志守候进程的脚本

xfs:X Window字型服务器,为本地和远程X服务器提供字型集

xntpd:网络时间服务器

ypbind:为NIS(网络信息系统)客户机激活ypbind服务进程

yppasswdd:NIS口令服务器

ypserv:NIS主服务器

 

2.交互式进程:shell应用程序

shell程序组成部分:脚本或程序的源文件

 

二.linux编程的基本知识

1.编译执行

处理过程分为:预处理—>编译—>汇编—>链接等4个过程 c或c++均采用此种方式

以C语言示例程序Hello World为例演示过程

a.预编译

p_w_picpath

b.编译

p_w_picpath

c.汇编

p_w_picpath

d.链接

p_w_picpath

2.解释执行:由解释器全程参与运行过程,每次读取一行,运行一行

Python:编程库

            程序控制结构,调用编程库完成程序编写

            库文件:功能模块,在编程中调用:通过其API

例:使用Pthon打印hello world

p_w_picpath

p_w_picpath

Bash:编程

            程序控制结构,调用机器上命令程序文件运行程序编写

            外部命令:个应用程序提供

例:使用bash shell打印hello world

p_w_picpath

p_w_picpath

3.两种编程思想

其一为:过程式编程,以指令为中心,设计算法,数据服务于算法

其二为:对象式编程,以数据为中心,设计数据结构(类)程序服务于数据结构

 

三.详解Bash编程

1.变量相关知识

变量的定义:可变的量,命令的内存空间

变量的生效范围:

                本地变量:当前shell

                环境变量:当前shell及其自进程

                局部变量:某个函数执行过程

变量类型:

               数值,字符:

               数值:整数,浮点

               字符:ASCII

               位置参数变量:在脚本中传递给脚本的参数

               特殊变量:$? 打印上一个命令执行结果0为正确执行1-255为错误执行

                                  $* 参数个数

                                  $@ 参数个数

                                  $$ ppid

                                  $# 参数总数

                                  $1-n 第一到第n个参数

变量类型的作用:

               存储空间,运算,存储格式

语言对变量类型的支持力度:

              强类型:变量类型严格区分 C,Java等

              弱类型:变量类型不严格区分,默认存储机制为字符 Bash,Python等

bash的变量使用特点:弱类型,无需事先声明

定义本地变量:

name=value

name:变量名

=:赋值符号

value:变量值

变量名:只能包含数字、字符和下划线,且不能以数字开头

引用变量 :${name} $name

引用类型:

弱引用:使用“”其内部的变量会替换为变量值

p_w_picpath

强引用:使用'' 其内部不会发生变量替换

p_w_picpath

命令引用:`COMMAND`,$(COMMAND)引用变量执行的结果

p_w_picpath

声明一个变量:declare -i name[=value]或let name=value

p_w_picpath

变量的生命周期:

            创建:执行name=value

            销毁:自动销毁 shell进程结束 手动销毁unset name

p_w_picpath

环境变量定义:被导出的本地变量,生效范围为本shell及其派生的子shell

export name[=value]

declare -x name[=value]

查看所有环境变量:env printenv export set

销毁:unset name

p_w_picpath

 

2.bash编程基础

脚本:文本文件

        运行脚本:运行一个bash进程,此进程负责从脚本文件中读取一个逻辑,由bash负责解释和运行此逻辑

启动脚本:

        (1)#bash /PATH/TO/SCRIPT_FILE

        (2)一个执行权限 #./PATH/TO/SCRIPT_FILE

格式:第一行:定格shebang

p_w_picpath

bash常用选项:-n检查脚本语法

                            -x调试执行脚本

                            -v显示详细信息

p_w_picpath

3.bash测试逻辑

测试方式:

根据运行的命令的状态结果

测试表达式:test [EXPR1] [EXRP2] 或 [ EXPR1 测试表达式 EXPR2 ]

 

整数测试:

$A -gt $B 是否大于

p_w_picpath错误返回

$A -ge $B  是否大于小于

p_w_picpath错误返回

$A -lt $B 是否小于

p_w_picpath正确返回

$A -le $B 是否小于等于

$A -eq $B 是否等于

$A -ne $B 是否不等于

 

字符串测试:

注:字符串比较字母排列的先后顺序,字符串比较需要使用` `

“$A”> "$B":是否大于

p_w_picpath正确返回

“$A”<“$B”:是否小于

p_w_picpath

“$A”==“$B” 是否等于

“$B”!=“$B”是否不等于

p_w_picpath

-z "$A" 是否为空,空则真

p_w_picpath

-n "$A" 是否为非空,非空为真

 

文件测试:测试文件的存在性以及属性

-e|-a $file 是否存在,存在为真

测试/etc/fstab是否存在

p_w_picpath

-f $file 文件是否存在且为普通文件

测试/etc/fstab是否为普通文件

p_w_picpath

-d $file 文件是否存在且为目录

测试/etc是否为目录

p_w_picpath

-h|-L $file 文件是否存在且为符号连接文件

测试/dev/cdrom是否为符号链接

p_w_picpath

-b $file 块设备文件

测试/dev/sda1是否为块设备文件

p_w_picpath

-S $file socket文件

p_w_picpath

权限测试:

-r $file 存在且具有可读权限

测试/etc/passwd是否有可读权限

p_w_picpath

-w $file 存在且有可写权限

测试/etc/passwd是否有可读权限

p_w_picpath

-x $file 存在且有可执行权限

p_w_picpath

-u $file 存在且有suid权限

p_w_picpath

-g $file 存在且有sgid权限

-o $file 存在且有sticky权限

-O $file 当前用户是否为指定文件的属主

-G $file 当前用户是否为指定文件的属主

 

双目操作符比较

$file1 -nt $file2 file1是否比file2新

p_w_picpath

$file1 -ot $file2 file1是否比file2旧

 

$file1 -ef $file2 file1和file2是否指向同一个inode即是否为硬链接

p_w_picpathhello为hello.sh的硬链接指向同一个inode

p_w_picpath

3.bash条件判断和循环语句

bash条件判断(选择执行)

语法格式:

if CONDITION;then if-true-分支;fi

p_w_picpath

if CONDITION;then if-true-分支 ;else if-else分支 ;fi

p_w_picpath

! CONDITION:取反

 

脚本参数(位置参数变量)

# ./script.sh /etc/fstab

$0 脚本本身

$1 第一个参数

$2 第二个参数

$n 第n个参数

p_w_picpath

shift可以对参数进行偏移

p_w_picpath

p_w_picpath

使用read命令可以实现交互式程序编写

常用参数:-p 给出提示语句 -t 超时时间

p_w_picpath

循环语句:

for 循环列表;do 执行的操作;done

p_w_picpath

while 循环列表;do 执行的操作;done

p_w_picpath

p_w_picpath

until 循环列表;do 执行的操作;done

 

循环:将循环体代码执行0,1或多次

进入条件:进入循环的条件

退出条件:循环终止的条件

for VAR in LIST;do 循环体;done

LIST:是由一个或多个空格或换行符分隔开的字符串组组成

 

组合测试条件:

条件间逻辑运算:

与:多个条件同时满足

或:多个条件满足其一即可

非:对指定的条件取反

表达式组合:

与:[ CONDITION1 -a CONDITION2 ]

p_w_picpath

或:[ CONDITION1 -o CONDITION2 ]

p_w_picpath

非:[ ! CONDITION ]

p_w_picpath

 

命令组合:

与:COMMAND1 && COMMAND2  其中&&为短路与操作,即当COMMAND1正确执行后COMMAND2才会被执行

p_w_picpath

或:COMMAND1 || COMMAND2 其中&&为短路或操作,即当COMMAND1没有被正确执行后COMMAND2才会被执行

p_w_picpath

与:! COMMAND

 

case语句:

简洁版的多分支if语句

使用场景:判断某变量的值是否为多分支的一种时使用

语法:

case $VAR in

PATTERN1)

分支1

;;

PATTERN2)

分支2

;;

PATTERNn)

分支n

;;

esac

输入一个数,10和20均显示false,50为true

跟马哥学linux (lesson 7)Bash脚本基础知识_第1张图片

 

二、课堂练习

1、写一个脚本:如果某路径不存在,则将其创建为目录;否则显示其存在,并显示内容类型;(不要怀疑,就是这么简单)

2、写一个脚本,完成如下功能;判断给定的两个数值,孰大孰小;给定数值的方法:脚本参数,命令交互;(使用read,依然如此简单)

3、求100以内所有奇数之和(至少用3种方法。是的这是我们的作业^_^)

4、写一个脚本实现如下功能:

(1) 传递两个文本文件路径给脚本;

(2) 显示两个文件中空白行数较多的文件及其空白行的个数;

(3) 显示两个文件中总行数较多的文件及其总行数;

5、写一个脚本

(1) 提示用户输入一个字符串;

(2) 判断:

如果输入的是quit,则退出脚本;

否则,则显示其输入的字符串内容;

6、写一个脚本,打印2^n表;n等于一个用户输入的值;(不好意思,我调皮了)

7、写一个脚本,写这么几个函数:函数1、实现给定的两个数值的之和;函数2、取给定两个数值的最大公约数;函数3、取给定两个数值的最小公倍数;关于函数的选定、两个数值的大小都将通过交互式输入来提供。

解答:

1.

#!/bin/bash    
aaa="/etc/aaa"   
if [ ! -e "$aaa" ]     
  then mkdir $aaa && echo "create successful."     
  else echo "$aaa has exist." && ls -l $aaa     
fi

p_w_picpath

2.

#!/bin/bash    
if [ $# -ne 2 ];then echo "Plz enter 2 numbers.";fi     
if [ $1 -gt $2 ];then echo $1 ">" $2     
  elif [ $1 -lt $2 ];then echo $1 "<" $2     
  elif [ $1 -eq $2 ];then echo $1 "=" $2     
  else echo "unkonw."     
fi

p_w_picpath

3.

方法一、

#!/bin/bash    
declare -i i     
declare -i sum=0     
for i in {1..100}     
  do if [ $(($i%2)) -ne 0 ];then sum=$i+$sum;fi     
done     
echo $sum

p_w_picpath

方法二、

#!/bin/bash    
declare -i aaa     
declare -i sum=0     
for aaa in `seq 1 2 100`     
  do sum=$aaa+$sum     
done     
echo $sum

p_w_picpath

方法三、

#!/bin/bash    
declare -i i     
declare -i sum=0     
declare -i oddsum=0     
declare -i evensum=0     
for i in {1..100}     
  do sum=$i+$sum     
    if [ $(($i%2)) -eq 0 ];then oddsum=$oddsum+$i;fi && evensum=$sum-$oddsum     
done     
echo $evensum

p_w_picpath

4.

#!/bin/bash    
if [ $# -ne 2 ]     
  then echo "Plz enter 2 files"     
  else sumline1=`cat $1|wc -l` sumline2=`cat $2|wc -l` blank1=`grep '^$' $1|wc -l` blank2=`grep '^$' $2|wc -l`     
    if [ $blank1 -gt $blank2 ];then echo "more blank line is $1 $blank1 lines"     
       else echo "more blank line is $2 $blank2 lines"     
    fi     
    if [ $sumline1 -gt $sumline2 ];then echo "more line is $1 $sumline1 lines"     
       else echo "more line is $2 $sumline2 lines"     
    fi     
fi

p_w_picpath

5.

#!/bin/bash    
while true     
do     
read -t 5 -p "Plz enter someting. " aaa     
  if [ $aaa == "quit" ];then exit     
    else echo $aaa     
  fi     
done

跟马哥学linux (lesson 7)Bash脚本基础知识_第2张图片

6.注:(次题目参考了@谢俊同学,并略加修改。)

[object Object]
#!/bin/bash
#
read -t 5 -p "please enter a number: " x
[ -z $x ]&&echo "Errot:please enter a number!"
count=2
for i in $(seq 0 $x);do
    if [ $i -eq 0 ];then
       echo -e $((2**$i))
    elif [ $i -eq 1 ];then
       echo -e $((2**$i))
    elif [ $i -gt 1 ];then
    count+=x2              # 字符的自加,感谢“天真的小同志”的指导
    echo $count=$[2**$i]
    else echo "Error:please enter a number!"
    fi
done
7.
#!/bin/bash
#
sum() {
read -p "Plz enter two number. " args1 args2
echo sum=$((args1+args2))
}

gcd() { #先求出其中任意两个数的最大公约数,再求这个最大公约数与第三个数的最大公约数,依次求下去,直到最后一个数为止。
read -p "Plz enter two number. " a b
c=$((a%b)) #对a,b进行取模运算
while [ "$c" -ne 0 ];do #当a,b的模不等于0时
gcd=$c #对gcd进行第一次赋值,gcd等于a,b的模
a=$b  #把上一次b的至赋给a
b=$c  #把上一次c的值赋给b
c=$((a%b)) #再一次进行取模,一直进行循环直到c的值为0
done
echo "gcd=$gcd"
}

lcm() { #最小公倍数为两个数的乘机除以最大公约数
read -p "Plz enter two number. " a b
c=$((a%b))
pro=$((a*b))
while [ "$c" -ne 0 ];do
gcd=$c
a=$b
b=$c
c=$((a%b))
done
echo "lcm=$((pro/gcd))"
}
case $1 in
sum)
sum
;;
gcd)
gcd
;;
lcm)
lcm
;;
*)
echo "Plz Usage `bashname`{sum|gcd|lcm}"
;;
esac

跟马哥学linux (lesson 7)Bash脚本基础知识_第3张图片

跟马哥学linux (lesson 7)Bash脚本基础知识_第4张图片

跟马哥学linux (lesson 7)Bash脚本基础知识_第5张图片