守护进程:运行在后台的进程,称之为守护进程也叫服务进程(提供某种特定的服务),多数会被设置为开机时自动启动;
交互式进程:与用户有交互方能实现功能的,shell应用程序
GUI:图形化的交互进程
CLI:命令形式交互进程
COMMAND
shell程序会进行词法分析区分哪些字符串是命令,哪些字符串是选项,哪些字符 串是参数
shell程序内建一部分命令(shell内建命令)
shell程序也能调用外部命令,外部命令的二进制源码存放在环境变量PATH指 定的路径中(外部命令)
fork() shell为每一个要执行的命令创建为一个子进程;
脚本或程序源文件:把要运行的一系列命令,写在文件中;
两种方式:
编译执行:预处理-->编译-->汇编-->链接;必须事先完成整个文本文件内容的语言转换为 二进制,处理后得到二进制程序文件提交给cpu执行
C, C++
解释执行:由解释器全程参与运行过程,每次读取一行并解释一行获得二进制,将结果提 交给cpu运行;
Python:编程库
程序控制结构,调用编程库完成程序编写;
可以调用库文件:功能模块,在编程中可调用;通过其API;
Bash:编程
程序控制结构,调用机器上命令程序文件进行程序编写;
调用外部命令:各应用程序提供;
bash过程式编程:
顺序执行:逐个执行文本文件中的命令
选择执行:只执行其中符合选择条件的一个分支
循环执行:一段代码要执行0,1或多遍
变量:一个命名了的内存空间,变量名可以理解为某内存空间的地址门牌号。通过 $变量名 可以获 得该变量代表的内存空间中所存放的值
bash环境中有如下几种变量:
本地变量:只在当前shell进程中生效的变量;
环境变量:在当前shell进程及其子进程生效的变量;
局部变量:某个函数执行过程中,该函数外无效;
位置参数变量:在脚本中引用传递给脚本的参数;在函数中引用传递给函数的参数;
特殊变量:$?:上一条命令的执行状态结果
$*:统计传递给脚本文件的参数列表
$@:统计传递给脚本文件的参数列表
$#:统计传递给脚本文件的参数数量
$$:表示当前进程的编号
变量类型:该变量所代表的内存空间所存放的值类型
数值,字符;
数值:
整数
浮点数
字符:
ASCII
120:
字符:1, 2, 0-->一个1代表一个字符用一个字节表示0000 0001
数值:120 --> 一个字节便能表示数值120,1111 1000
变量类型的作用:
存储空间:声明变量类型有利于节省存储空间的节省
运算:声明变量类型为数值型才能进行变量运算
存储格式:声明变量确定变量是以字符还是数值存储
语言对变量类型的支持力度:
强类型:严格区分变量类型,必须事先声明
弱类型:变量类型不严格区分;
bash默认存储机制:存储为字符
bash的变量使用特点:弱类型、无须事先声明;
凡是自定义的变量尽量小写 避开系统自身的变量名
本地变量:
name=value
name: 变量名
=:赋值符号
value:值
变量名:只能包含数字、字母和下划线;且不能以数字开头;
引用变量:$name
${name}(用在变量内容后面加字符修饰)例如 :name=dog 想表示dogs时 引用${name}s
引用:
弱引用: "", 其内部的变量引用会被替换为变量值;
强引用:'',其内部的变量引用会保持原有字符;
命令引用:`COMMAND`, $(COMMAND),引用命令的执行结果;
示例
[root@pks ~]# s1=dog ##设定本地变量s1 [root@pks ~]# echo "$s1" ##使用弱引用“”变量,替换成变量值 dog [root@pks ~]# echo '$s1' ##使用强引用‘’变量,保留变量名称的字符 $s1 [root@pks ~]# echo $(ls /mnt) ##使用命令替换 取得命令的执行结果 a centos gcc-4.8.3-9.el7.x86_64.rpm gcc5-5.1.1+r225724-1.1.x86_64.rpm grub.conf host.conf hosts hosts-test k p prelink.cache prelink.conf y [root@pks ~]# echo "${s1}s" ##为变量值后跟字符使用${变量} dogs
声明为整型:
declare -i name[=value]
let name=value
声明整数类型和在没有声明整数类型的情况下其结果一样,这是因为bash为弱类型、 无须事先声明,在使用变量进行运算的时候会进行隐式转行。
查看所有当前的本地变量:set
生命周期:
创建:从变量赋值开始
销毁:
自动销毁:shell进程终止;
手动销毁:unset name
[root@pks ~]# unset s1 [root@pks ~]# echo "$s1" [root@pks ~]#
环境变量:
用”导出“的方式使本地变量升级为环境变量
export name[=value]
declare -x name[=value]
[root@pks ~]# s1=dog [root@pks ~]# echo "$s1" dog [root@pks ~]# bash ##开一个子bash进程 [root@pks ~]# echo "$s1" ##在子bash进程查无s1变量 [root@pks ~]# exit ##退出bash子进程 [root@pks ~]# export s1 ##在当前进程中声明s1为环境变量 [root@pks ~]# bash [root@pks ~]# echo "$s1" ##在子bash进程查有s1变量,其值也为dog dog
查看所有环境变量:env, printenv, export
生命周期:
创建:从变量赋值开始
销毁:unset name
脚本:文本文件
运行脚本:事实上是创建一个bash子进程,此进程负责从脚本文件中读取一个执行逻辑,而后由 bash进程负责解析并运行此逻辑;
启动脚本:
(1) # bash /PATH/TO/SCRIPT_FILE
(2) 给予脚本文件执行权限,使用如下命令
# ./PATH/TO/SCRIPT_FILE
脚本文件的开头shebang:
#!/bin/bash,指明解释器的路径
第一行:顶格给出shebang
注释行:#为注释所用不会被bash进程解析该段字符
bash的常用选项:
-n: 检查脚本中的语法错误;
-x:调试执行脚本;(会将执行过程一步步显示出来,便于逻辑调试)
命令状态结果:
bash进程使用特殊变量#?用于追踪执行的命令成功与否的状态:
0: 成功
1-255:失败
布尔型:
“真”:成功
“假”:失败
可以自定义脚本的执行状态状态结果:
exit [n]
注意:脚本中任何位置执行了exit命令即会终止当前shell进程,如果有自定义的执行状态 值并将该值提交给特殊变量;
特殊设备:
/dev/null: 空,bit buckets,吞下所有数据,并直接丢弃;
取命令执行结果状态而不需要命令的执行结果时,可以输出重定向&> /dev/null
/dev/zero:吐出一堆0;
脚本参数(位置参数变量):
# ./script.sh /etc/fstab /etc/grub2.cfg
$0(脚本本身)
$1(脚本的第一个参数 /etc/fstab )
$2(脚本的第一个参数 /etc/grub2.cfg)
位置参数变量:$1, $2, ...
${10},双位数以上的变量引用时需用{}包裹数值
[root@pks var]# cat cat.sh #!/bin/bash # cat $1 echo "----------" cat $2
[root@pks var]# ./cat.sh /etc/fstab /etc/host.conf # # /etc/fstab # Created by anaconda on Wed Aug 19 21:28:16 2015 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # UUID=f745eac2-6b4c-48e8-bae5-aa43cd3d313a / ext4 defaults 1 1 UUID=baaa7f26-f28c-4db8-91fd-10c0d14ea07d /boot ext4 defaults 1 2 UUID=6becb873-32d7-4c9a-bfb8-838f021ca0e3 swap swap defaults 0 0 /dev/sdb2 /mydata ext4 defaults 1 0 tmpfs /dev/shm tmpfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 ---------- multi on
特殊变量:
$?: 命令的执行状态结果;
$#: 传递给脚本或函数的参数的个数;
$*和$@: 引用传递给脚本或函数的参数列表;
shift [n]:代表一次轮替掉n个参数,(默认轮替掉一个参数) 例如$1是a,$2是b,$3为c
shift后$1为b ,shift 2后$1为c
[root@pks var]# cat cat1.sh #!/bin/bash # echo "$#" echo "----------" echo "$*" echo "----------" echo "$@" echo "----------" echo "$1" shift echo "----------" echo "$1" [root@pks var]# chmod +x cat1.sh [root@pks var]# bash cat1.sh /etc/fstab /etc/host.conf 2 ##echo "$#" ---------- /etc/fstab /etc/host.conf ##echo "$*" ---------- /etc/fstab /etc/host.conf ##echo "$@" ---------- /etc/fstab ##echo "$1" ---------- /etc/host.conf ## shift 之后第一个变量被替换
与用户交互:接受用户输入参数
read命令:
read [options] VAR...
-p "PROMPT" (用于做说明提示)
-t timeout (说明如果多长时间没输入将会结束脚本)
当输入超过参数数量时,按空格依次赋值参数,之后输入所剩的部分全赋值给最后一个参数
当参数数量多余输入时,按空格依次赋值参数,没有被赋值的变量值为空
[root@pks var]# read f1 f2 hou are you [root@pks var]# echo "$f1" hou [root@pks var]# echo "$f2" are you [root@pks var]# read f1 f2 f3 hello you [root@pks var]# echo "$f1" hello [root@pks var]# echo "$f2" you [root@pks var]# echo "$f3" [root@pks var]#
命令引用:
`COMMAND`, $(COMMAND)
引用命令的执行结果;
(1) ls `which cat`
(2) lines=$(wc -l /etc/fstab | cut -d' ' -f1)
算术运算:
+, -, *, /, %, **
(1) $[$A+$B]
(2) $(($A+$B))
(3) let VARIABLE=$A+$B
(4) VARIABLE=$(expr $A + $B)
[root@pks var]# A=5 [root@pks var]# B=7 [root@pks var]# C=$[$A+$B] [root@pks var]# echo "$C" 12 [root@pks var]# D=$(($A+$B)) [root@pks var]# echo "$D" 12 [root@pks var]# let E=$A+$B [root@pks var]# echo "$E" 12 [root@pks var]# F=$(expr $A+$B) [root@pks var]# echo "$F" 5+7 [root@pks var]# F=$(expr $A + $B) ##加号之间必须有空格 [root@pks var]# echo "$F" 12
增强型赋值:
+=
let sum+=$i相当于sum=$[$sum+$i]
-=, *=, /=, %=等用法和+=是一样的
let count=$[$count+1] --> let count+=1 --> let count++
let count=$[$count-1] --> let count-=1 --> let count--
示例:显示/etc目录下所有普通文件列表,而后统计一共有多少个文件;
#!/bin/bash
#
declare -i count=0 ##定义计数器 整型变量count
for file in /etc/*; do ##使用通配方法生产/etc文件目录下的文件列表
if [ -f $file ]; then
let count++ ##当是普通文件时计数器变量count自己+1
echo "$count $file"
fi
done
echo "Total: $count files."
测试表达式:
整数测试:-gt, -lt, -ge, -le, -eq, -ne
字符串测试:==, >, <, !=, -z, -n, =~
注意:
(1) 字符串等值比较测试:[ "$hostname" == 'localhost' ]
(2) 模式匹配测试:[[ "STRING" =~ PATTERN ]]
[root@pks var]# str1=hello [root@pks var]# [ "$str1" == 'hello' ] [root@pks var]# echo "$?" 0 [root@pks var]# [[ "$str1" =~ hel* ]] [root@pks var]# echo "$?" 0 [root@pks var]# [ "$str1" != 'hel' ] [root@pks var]# echo "$?" 0 [root@pks var]# [ "$str1" = 'hel' ] [root@pks var]# echo "$?" 1 [root@pks var]#
组合测试条件:
条件间逻辑运算:
与:多个条件要同时满足;
或:多个条件满足其一即可;
非:对指定的条件取反;
表达式组合:
与:[[ CONDITION1 -a CONDITION2 ]]
或:[[ CONDITION1 -o CONDITION2 ]]
非:[ ! CONDITION ]
命令组合:
与:COMMAND1 && COMMAND2 <-- [ EXPR1 ] && [ EXPR2 ]
或:COMMAND1 || COMMAND2
非:! COMMAND
短路操作符:&&
false && true = false
false && false = false
true && false = false
true && true = true
COMMAND1 && COMMAND2 只有当COMMAND1成立时,才会执行COMMAND2;效果等同下 面的if
if COMMAND1; then
COMMAND2
fi
短路操作符:||
true || true = true
true || false = true
false || true = true
false || false = false
COMMAND1 && COMMAND2 只有当COMMAND1不成立时,才会执行COMMAND2;效果等同 下面的if
if ! COMMAND1; then
COMMAND2
fi
COMMAND1 && COMMAND2 || COMMAND3 只有当COMMAND1成立时,才会执行COMMAND2; 如果COMMADN1不成立则是COMMAND1 && COMMAND2整个不成立,便会执行command3
效果等同下面的if
if COMMAND1; then
COMMAND2
else
COMMAND3
fi
注意:&&的级别高于||
函数:
function: 功能
把一段具有独立功能代码封装在一起,并给予命名;后续用到时,可直接通过给定函数名来调用整体代码;
函数作用:
代码重用;
模块化编程;将一段代码放在其他文件中,运行脚本文件时可以读入那其他文件中的 代码
函数的使用方法:
先定义:编写函数代码
后调用:给出函数名,还可按需传递参数
定义方法:
(1) function f_name {
函数体
}
(2) f_name() {
函数体
}
调用函数:
f_name [argu1, argu2, ...]
自定义函数状态返回值:
return [#]
0: 成功
1-255:失败
注意:函数代码执行时,一旦遇到return,函数代码终止运行,函数返回;
模块化编程
功能:把脚本文件中的代码分隔为多段,放在不同的文件中
假设/root/bin/srv目录有两个文件:
(1) 函数文件
(2) 脚本文件
为脚本使用配置文件
一个文件中只定义变量
脚本文件source此变量定义的文件
变量的作用域:
局部变量:
local VARIABLE=value
存活时间:
函数执行开始,至函数返回结束;