编程简介:
脚本编程 : 利用系统上的命令及编程组件进行编程
完整编程:利用库或编程组件进行编程:
编程模型:过程是编程语言,面向对象的编辑语言
程序=指令+数据
过程式:一指令为中心来组织代码,数据是服务于代码:
顺序执行
选择执行
循环执行
代表:C,bash
对象式:以数据为 中心来组织代码,围绕数据来组织指令:
程序员首先编写许多类(class):实列化对象,methed;
代表:java, C++,python
- 过程式编程,解释运行,非完整的编写语言,依赖于外部程序文件运行:
shell 脚本:
- 脚本文件的第一行,顶格:给出shebang,解释器路径,用于指明解释执行当前脚本的解释器脚本文件:
- 常见的解释器:
- !/bin/bash
- !/usr/bin/python
- !/usr/bin/perl
-
脚本文件格式:
- 第一行,顶格:#!/bin/bash
- 注释:#
- 代码注释:
- 数据类型:字符型, 数值型 , 弱引行:字符型
算术运算:
- +-*/%**
- let VAR=expression
- VAR=$[expression]
- VAR=$((expression))
- VAR=(espr argu1 argu2 argu3)
- 有时候乘法需要转义;
增强型赋值:
- 变量做某种算数运算后回存至此变量中;
- let i=$i+#
- let i+=#
- +=, -=,*=,/=,%=
- 自增:
- VAR=$[$VAR +1]
- let VAR+=1
- let VAR ++
- 自减
- VAR=$[$VAR -1]
- let VAR-=1
- let VAR --
- 练习;
- 1. 计算/etc/passwd文件中的第10个和第二十个用户id号之和
- id1=$(cat /etc/passwd |head -10|tail -1|cut -d: -f3)
- id2=$(cat /etc/passwd |head -20|tail -1|cut -d: -f3)
- sum=$[id1+id2]
- 2. 计算/etc/rc.d/init.d/functions和/etc/inittab之间空白行之和
- SPACE1=$(grep -c "^$" /etc/rc.d/init.d/functions)
- SPACE2=$(grep -c "^$" /etc/inittab)
- sum=$[SPACE1+SPACE2]
- echo "this is $sum"
条件测试:
- 判断某需求是否满足要求.需要由测试机制来实现;
- 如何编写测试表达式以实现所需的测试
- 1 . 执行命令,并利用命令状态返回值来判断;
- 0:成功
- 1-255:失败
- 2. 测试表达式
- test EXPRSSION
- [EXPRSSION]
- [[EXPRSSION]]
- 两端必须有空白字符,负责语法错误
bash 的测试类型:
- 数值测试
- 字符串测式
- 文件测试
- 数值测试: 数值比较
- -eq: 是否等于;[$num1 -eq $num2]
- -ne: 是否不等于
- -gt: 是否大于;
- -ge: 是否小于
- -lt: 是否小于
- -le: 是否小于等于;
- 字符串测试
- == :是否等于
- >: 是否大于
- <: 是否小于
- !=:是否不等于
- =~:左侧字符串是否能够被右侧的PATTERN所匹配;
- -z: "STRING":判断指定的字符串是否为空;空则为真,不空则假
- -n:"STRING":判断指定的字符串是否不空,不空为真,空则假;
- 文件测试:
- -a:FILE
- -e:FILE
- 文件的存在性性测试,存在则为真,否则则为假;
- -b: 测试是否存在并且为,设备文件;
- -c: 是否存在是否为字符设备文件;
- -d:是否存在并且为目录文件;
- -f:是否存在且为普通文件;
- -h:是否存在且为符号链接文件
- -p:是否存在切位管道文件;
- -s:文件是否存在且为套接字文件;
- 文件权限测试:
- -r FIEL: 是否存在并且对当前用户可读
- -w: 是否存在并且 对当前用户可写
- -x: 是否存在并且 对当前用户可执行;
- 特殊权限测试:
- -u:是否存在且拥有suid权限
- -g:是否存在且拥有sgid权限
- -k:是否存在并且拥有stiky权限
- 文件是否有内容:
- -s: 是否有内容;
- 时间戳测试:
- -N:文件自从上次读操作后是否被修改过;
- 从属关系测试:
- -O FIEL:当前用户是否为文件的属主;
- -GFIEL:当前用户是否属于文件 的属组
- 双目测试:
- FILE1 -ef FILE2:用来测试FILE1与FILE2是否指向同一个文件系统的相同inode的硬件连接;
- FILE1 -nt FILE2 :FILE1是否新于FILE2
- FILE1 -ot FILE2 :FILE1是都旧与FILE2;
- 组合和测试条件
- 逻辑运算
- 第一种方式
- COMMAND1&&COMMAND2
- COMMAND1|| COMMAND2
- ! COMMAND
- [- O FILE]&&[-RFILE]
- 第二种方式
- EXPRESSION1 -a EXPRESSION2
- EXPRESSION1-o EXPRESSION2
- !EXPRESSION
- [-O FILE -a -x FILE]
- 字符串要加引用;
- 要用[[ ]]
- 脚本的状态返回值:
- 默认是脚本中执行的最后一条件命令的状态返回值
- 自定义状态返回值退出状态码:
- exit n:n 为自己指定状态码
- shell进程与exit则会停止退出
- 向脚本传递参数:
- 位置参数变量
- 引用方式:
- $1,$2.....位置参数变量比如写一个op的脚本将其传递 op1, op2,其直接引用参数值
- 轮替:shift将其指定的参数轮替
- shift [n]: 位置参数轮替
- 练习:
- 写一个脚本,通过命令传递两个文本路经给脚本,计算其参数之和;
- file1=$(grep -c "^$" $1)
- file2=$(grep -c "^$" $2)
- sum=$[ file1 + file2]
- echo "is a $sum"
- 特殊变量:
- $0:脚本文件路径本身; echo $0
- $#:脚本参数的个数;
- $*:整个脚本参数 整体字符串
- $@:所有参数,为单个字符串
- 过程式编程语言的代码执行顺序:
- 顺序执行: 逐条运行
-
选择执行:
- 代码有一个份支:条件满足是才会执行
- 两个或以上的分支: 只会执行其中一个满足条件的分支
-
循环执行:
- 代码片段(循环体)要执行0, 1或多个来回;
-
选择执行:
- if语句可嵌套
- 单分支的if语句
- if 测试条件
- then
- 代码分支
- fi
- 双分支的if语句:
- if 测试条件;then
- 条件为真时执行的分支
- else
- 条件为假时执行的分支
- fi
- 示例:
- 1.通过参数传递一个用户
- 1. if [$# -lt 1 ]:then
- echo "At least one username"
- exit2
- fi
- if ! grep "^$1\>" /etc/passwd &> /dev/null:then
- useradd $1
- echo $1 |passwd --stdin $1 &> /dev/null
- echo "Add user $1 finished"
- fi
- 2. if [$# -lt 1 ]:then
- echo "At least one username"
- exit2
- fi
- if grep "^$1\>" /etc/passwd &> /dev/null:then
- echo "User $1 exists"
- useradd $1
- echo $1 |passwd --stdin $1 &> /dev/null
- echo "Add user $1 finished"
- fi
- 2. 通过命令参数给定两个数字,输出其中较大的数值;
- if [ $# -lt 2 ];then
- echo "Two integers"
- exit 2
- fi
- if [ $1 -ge $2 ];then
- echo" Max number: $1"
- else
- echo "Max number: $2
- fi
- 多分支的if语句
- if CONDITION1;then
- 条件1为真分支
- elif CONDTION2;then
- 条件2为真分支
- elif CONDITIOND3;then
- 条件三为真分支
- elif CONDITIONn;then
- 条件n为真分支
- else
- 所有条件均不满足的分支
- fi
- 注意:即便多个条件可能同时都满足,分支只会执行其中一个,首先测试为"真"
- 练习:
- 1,传递一个参数给脚本,此参数为用户ID;
- [ $# -lt 1 ] && echo "at least on user name" &&exit 1
- id $1 &>/dev/null && echo " no such user "&&exit 2
- userid=$(id -u $1)
- if [ $userid -eq 0 ];then
- echo "root"
- elif [ $userid -ge 1000 ];then
- echo "login user"
- else
- echo "System user"
- fi
- 2.通过命令参数给定一个用户名,判断其ID号是偶数还是奇数;
- if [ $# -lt 1 ] ;then
- echo "please input one userid"
- exit1
- fi
- ID=$(id -u $1)
- if [[ $[$ID%2] == 0 ]];then
- echo" this even :$ID"
- exit2
- else
- echo "this odd :$ID"
- exit3
- fi
- 3.通过命令参数给定两个文件名,如果某文件不存在,则结束脚本执行,
- 都存在时返回每个文件的行数,并说明其中行数较多的文件;
- if [ $# -lt 2 ];then
- echo "please input filename"
- exit 1
- fi
- one=$(grep "^.*$" $1|wc -l )
- two=$(grep "^.*$" $2|wc -l )
- if ! [ $one == 0 ] && ! [ $two == 0 ] && [ $one -gt $two ];then
- echo " this file :$one,big"
- else
- echo "this file :$one ,samll"
bash脚本:循环
- 循环执行:将一段代码重复执行0,1或多次'
- 进入条件; 条件满足时才进入循环'
- 退出条件:每个循环都应该由退出条件,以有机会退出程序;
- for 循环
- whil 循环
- until 循环
- for循环:
- 两种格式:
- 1.遍历列表
- 2.控制变量
- 遍历列表:
- for VARAIBIE in LIST ;do
- done
- 例: for username in user1 user2 user3;do
- if id $username &> /dev /null;then
- echo"$username exists"
- else $username && echo " Add user$username finished"
- done
- for fileame in 1 2 3 4 5 6;do
- touch /tmp/f$filename
- done
- 进入条件:"只要列表有元素,即可进入循环;"将list 的shu
- 退出条件: 完成遍历列表,及退出;
-
LISTTDE的生成方式:
- 1 ,直接给出:
- 2 ,整数列表
- (a) {start..end}
- (b) seq[start [incremtal]]last
- 3返回列表的命令
- 4,glob
- 5,变量引用
- 示例 :求100以内所有正整数之和;
- declare -i L=0
- for o in {1,,100};do
- L=$[$L+$o]
- done
- echo $L
- 练习:
- 1,分别求100以内所有偶数之和,以及所有奇数之和;
- declare -i O=0
- sum=$(seq 1 2 100)
- for o in $sum;do
- O=$[$o+$O]
- done
- echo $O
- sum1=$( seq 2 2 100)
- for P in $sum1;do
- O=$[$P+$O]
- done
- echo $O
- 2,计算当前系统上所有用户的id之和;
- declare -i O=0
- S=$(cat /etc/passwd |cut -d":" -f3|sort|uniq -c|sort -nr)
- for o in $S;do
- O=$[$O+$o]
- echo " $O"
- done