一、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.预编译
b.编译
c.汇编
d.链接
2.解释执行:由解释器全程参与运行过程,每次读取一行,运行一行
Python:编程库
程序控制结构,调用编程库完成程序编写
库文件:功能模块,在编程中调用:通过其API
例:使用Pthon打印hello world
Bash:编程
程序控制结构,调用机器上命令程序文件运行程序编写
外部命令:个应用程序提供
例:使用bash shell打印hello world
3.两种编程思想
其一为:过程式编程,以指令为中心,设计算法,数据服务于算法
其二为:对象式编程,以数据为中心,设计数据结构(类)程序服务于数据结构
三.详解Bash编程
1.变量相关知识
变量的定义:可变的量,命令的内存空间
变量的生效范围:
本地变量:当前shell
环境变量:当前shell及其自进程
局部变量:某个函数执行过程
变量类型:
数值,字符:
数值:整数,浮点
字符:ASCII
位置参数变量:在脚本中传递给脚本的参数
特殊变量:$? 打印上一个命令执行结果0为正确执行1-255为错误执行
$* 参数个数
$@ 参数个数
$$ ppid
$# 参数总数
$1-n 第一到第n个参数
变量类型的作用:
存储空间,运算,存储格式
语言对变量类型的支持力度:
强类型:变量类型严格区分 C,Java等
弱类型:变量类型不严格区分,默认存储机制为字符 Bash,Python等
bash的变量使用特点:弱类型,无需事先声明
定义本地变量:
name=value
name:变量名
=:赋值符号
value:变量值
变量名:只能包含数字、字符和下划线,且不能以数字开头
引用变量 :${name} $name
引用类型:
弱引用:使用“”其内部的变量会替换为变量值
强引用:使用'' 其内部不会发生变量替换
命令引用:`COMMAND`,$(COMMAND)引用变量执行的结果
声明一个变量:declare -i name[=value]或let name=value
变量的生命周期:
创建:执行name=value
销毁:自动销毁 shell进程结束 手动销毁unset name
环境变量定义:被导出的本地变量,生效范围为本shell及其派生的子shell
export name[=value]
declare -x name[=value]
查看所有环境变量:env printenv export set
销毁:unset name
2.bash编程基础
脚本:文本文件
运行脚本:运行一个bash进程,此进程负责从脚本文件中读取一个逻辑,由bash负责解释和运行此逻辑
启动脚本:
(1)#bash /PATH/TO/SCRIPT_FILE
(2)一个执行权限 #./PATH/TO/SCRIPT_FILE
格式:第一行:定格shebang
bash常用选项:-n检查脚本语法
-x调试执行脚本
-v显示详细信息
3.bash测试逻辑
测试方式:
根据运行的命令的状态结果
测试表达式:test [EXPR1] [EXRP2] 或 [ EXPR1 测试表达式 EXPR2 ]
整数测试:
$A -gt $B 是否大于
错误返回
$A -ge $B 是否大于小于
错误返回
$A -lt $B 是否小于
正确返回
$A -le $B 是否小于等于
$A -eq $B 是否等于
$A -ne $B 是否不等于
字符串测试:
注:字符串比较字母排列的先后顺序,字符串比较需要使用[[ ]]
“$A”> "$B":是否大于
正确返回
“$A”<“$B”:是否小于
“$A”==“$B” 是否等于
“$B”!=“$B”是否不等于
-z "$A" 是否为空,空则真
-n "$A" 是否为非空,非空为真
文件测试:测试文件的存在性以及属性
-e|-a $file 是否存在,存在为真
测试/etc/fstab是否存在
-f $file 文件是否存在且为普通文件
测试/etc/fstab是否为普通文件
-d $file 文件是否存在且为目录
测试/etc是否为目录
-h|-L $file 文件是否存在且为符号连接文件
测试/dev/cdrom是否为符号链接
-b $file 块设备文件
测试/dev/sda1是否为块设备文件
-S $file socket文件
权限测试:
-r $file 存在且具有可读权限
测试/etc/passwd是否有可读权限
-w $file 存在且有可写权限
测试/etc/passwd是否有可读权限
-x $file 存在且有可执行权限
-u $file 存在且有suid权限
-g $file 存在且有sgid权限
-o $file 存在且有sticky权限
-O $file 当前用户是否为指定文件的属主
-G $file 当前用户是否为指定文件的属主
双目操作符比较
$file1 -nt $file2 file1是否比file2新
$file1 -ot $file2 file1是否比file2旧
$file1 -ef $file2 file1和file2是否指向同一个inode即是否为硬链接
hello为hello.sh的硬链接指向同一个inode
3.bash条件判断和循环语句
bash条件判断(选择执行)
语法格式:
if CONDITION;then if-true-分支;fi
if CONDITION;then if-true-分支 ;else if-else分支 ;fi
! CONDITION:取反
脚本参数(位置参数变量)
# ./script.sh /etc/fstab
$0 脚本本身
$1 第一个参数
$2 第二个参数
$n 第n个参数
shift可以对参数进行偏移
使用read命令可以实现交互式程序编写
常用参数:-p 给出提示语句 -t 超时时间
循环语句:
for 循环列表;do 执行的操作;done
while 循环列表;do 执行的操作;done
until 循环列表;do 执行的操作;done
循环:将循环体代码执行0,1或多次
进入条件:进入循环的条件
退出条件:循环终止的条件
for VAR in LIST;do 循环体;done
LIST:是由一个或多个空格或换行符分隔开的字符串组组成
组合测试条件:
条件间逻辑运算:
与:多个条件同时满足
或:多个条件满足其一即可
非:对指定的条件取反
表达式组合:
与:[ CONDITION1 -a CONDITION2 ]
或:[ CONDITION1 -o CONDITION2 ]
非:[ ! CONDITION ]
命令组合:
与:COMMAND1 && COMMAND2 其中&&为短路与操作,即当COMMAND1正确执行后COMMAND2才会被执行
或:COMMAND1 || COMMAND2 其中&&为短路或操作,即当COMMAND1没有被正确执行后COMMAND2才会被执行
与:! COMMAND
case语句:
简洁版的多分支if语句
使用场景:判断某变量的值是否为多分支的一种时使用
语法:
case $VAR in
PATTERN1)
分支1
;;
PATTERN2)
分支2
;;
PATTERNn)
分支n
;;
esac
输入一个数,10和20均显示false,50为true
二、课堂练习
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
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
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
方法二、
#!/bin/bash declare -i aaa declare -i sum=0 for aaa in `seq 1 2 100` do sum=$aaa+$sum done echo $sum
方法三、
#!/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
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
5.
#!/bin/bash while true do read -t 5 -p "Plz enter someting. " aaa if [ $aaa == "quit" ];then exit else echo $aaa fi done
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