一:关于语言
1)编译性语言
编译型语言多半运作于底层,所处理的是字节、整数、浮点数或其它及其机器层经的对象。处理过程为:源程序--预处理--编译--汇编--链接,编译性语言为静态语言。
2)解释性语言
解释性语言读入程序代码并将其转化为内部的形式加以执行。处理过程:解释性(文本文件)-解释器去读取并执行。解释性语言为动态语言。
二:基础
变量类型
linux脚本中的变量不需要事先声明,而是直接定义使用(这点不同于其他高级编程语言中变量的使用)bash变量类型分为本地变量和环境变量。
本地变量:只对当前的shell有效,对其他shell及其子shell没效
环境变量:对当前shell进程及其子shell有效,对其它的shell进程无效。
位置变量:$1, $2, ..., ${10};$1为第一个输入的变量$0为函数的本身,
特殊变量:$?
特殊变量:$#和$@为总共输入变量的数量。 取用户输入参数的个数
特殊变量:$*表示所有这些参数都被双引号引住。若一个脚本接收两个参数,$*等于$1$2;$@表示所有这些参数都分别被双引号引住
变量的引用 " ":弱引用,里面的变量会被替换;
' ':强引用,里面的所有字符都是字面量,直接输出.
自定义shell的状态返回值
exit [n]
自定义一个数的值
declare -i a=0
数值运算
let num++ 每成功执行一次自动添加一次。
交互式编程
read -p "输入说明: " a
-t :超时结束
read -p "PLZ inpit you name: " -t 3 :请输入用户名,超时3秒结束输入。
变量的赋值
使用变量无需事先声明,同时变量名的命名须遵循如下规则:
1)首个字符必须为字母(a-z,A-Z)
2)中间不能有空格,可以使用下划线(_)
3)不能使用标点符号
4)不能使用bash里的关键字(可用help命令查看保留关键字)
需要给变量赋值时可以使用:变量名=变量的值,要取用一个变量的值,只需在变量名前面加一个$ ( 注意: 给变量赋值的时候,不能在”=”两边留空格 )
变量的赋值:var_name=var_value
显示变量的值使用:echo $var_name
另外我们可以将一个命令的的执行结果赋值给一个变量
三:shell中括号的用法
1)符号$后的括号
${a} 变量a的值, 在不引起歧义的情况下可以省略大括号。
$(cmd) 命令替换, 结果为shell命令cmd的输出, 和`cmd`效果相同, 不过某些Shell版本不支持$()形式的命令替换, 如tcsh。
$((exp)) 和`expr exp`效果相同, 计算数学表达式exp的数值, 其中exp只要符合C语言的运算规则即可, 甚至三目运算符和逻辑表达式都可以计算。
2)多条命令执行
(cmd1;cmd2;cmd3) 新开一个子shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后可以没有分号。
{ cmd1;cmd2;cmd3;} 在当前shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后必须有分号, 第一条命令和左括号之间必须用空格隔开。
对{}和()而言, 括号中的重定向符只影响该条命令, 而括号外的重定向符影响到括号中的所有命令。
3)双括号的特殊用
(()) 增强括号的用法, 常用于算术运算比较. 双括号中的变量可以不使用$符号前缀, 只要括号中的表达式符合C语言运算规则, 支持多个表达式用逗号分开。比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in `seq 0 4`或者for i in {0..4},再如可以直接使用if (($i<5)), 如果使用中括号, 则为if [ $i -lt 5 ].
[[]] 增强方括号用法, 常用于字符串的比较. 主要用于条件测试, 双括号中的表达式可以使用&&, ||, <, >等C语言语法。比如可以直接使用if [[ $a -ne 1 && $a -ne 2 ]], 如果不使用双括号, 则为if [ $a -ne 1] && [ $a -ne 2 ]或者if [ $a -ne 1 -a $a -ne 2 ].
四:命令的逻辑关系
1)逻辑与&&
command1&&command2
command1为真是执行command2;为假时不在执行command2
2)逻辑||
command1||command2
command1为假时执行command2;为真时不执行执行command2
3)逻辑非!
!command
比命令的执行结果取反
例:
五:条件测试
1)文件类型测试
判断文件的存在性及属性
[ -e filename ] :文件存在则为真。
[ -f file ]:文件存在且是一个普通文件。
[ -d directory ]:存在并且为目录文件。
[ -b block ]:存在且是一个快设备。
[ -L Filer]:存在且是一个符号连接文件。
[ -s Filer]:存在且是一个非空文件。
2)文件的执行权限
[ -r filename ]:存在可读权限
[ -w filename ]:存在可写权限
[ -x filename ]:存在可执行权限
[ -N filename ]:最后一次修改时间比最近一次访问时间距现在时间还近。
[ file1 -nt file2 ]:file1最后一次修改时间比file2还要新则为真。
[ file1 -ot file2 ]:file1旧于file2为真
[[ express ]] (代表关键字)
3)整数测试
比较两个数谁大谁小。
关于整数测试的符号有:
-gt(大于) -ge(大于等于)
-lt(小于) -le(小于等于)
-eq(等于) -ne(不等于)
整数测试需要放在[ ]中且括号内两边和数字之间及等号与数字之间要有空格
>; <; >=; <=; =; !=
要放在(( ))进行比较。
4)字符串测试
字符串比较
= 等于,如:if [[ "$a" = "$b" ]]; == 等于,如:if [[ "$a" == "$b" ]],与=等价
字符串要有引号,且字符串两边要有空格。引用变量时要有双引号
双目操作符
>(大于) ;<(小于) ;!=(不等于) =(等于)
模式匹配
[[ "$var" =~ PATTERN ]]
单目操作符
-z "string" 测试string字符串是否为空 .空为真
-n "string" 测试string字符串是否不为空 .不空为真
条件测试一般要用[[ ]]
注意比较运算只在同一中类型进行比较。
六:组合条件测试
与: [ condition1 -a condition2 ]
两个都满足即可生效
或: [ conditionl -o condition2 ]
满足其中一个条件即可生效
非: [ -not condition ]
如果不用中括号的话
与:condition1 && condition2
或:condition1 || condition2
非:!condition
![ a -o b ] = [ !a -a !b ]
![ a -a b ] = [ !a -o !b ]
六:算数运算
1) let sum=$n1+$n2
2) sum=$[$n1+$n2] $[ ]只能进行整数运算
3) expr 1 + 2
4) num=$((1+2))
七:shell脚本中的控制语句
1)if选择语句
单分支语句 双分支语句 多分支语句
if 测试条件;then if 条件;then if 条件1;then
statement1 statement1 statement1
statement2 else elif 条件2;then
fi statement2 statement2
fi elif 条件3;then
......
fi
#!/bin/bash #表示条件状态为假时执行此语句。 if ! id $username &> /dev/null;then useradd $username fi #!/bin/bash # if id $1 &> /dev/null;then UserID= `id -u $1` #用户存在,取用户的id号。 echo "The User ID is $UserID" fi #! /bin/bash # if [ $1 -ge $2 ];then echo "the max num is $1" else echo "the max num is $2" fi #!/bin/bash # 取一串数值的最大值 declare -i num=0 for i in $*; do if [ $num -lt $i ];then num=$i fi done #根据命令成功与否当作执行条件,则if语句后必须跟命令本身且不能引用。 if grep "^[[:space:]]*$" $1 &> /dev/null; then echo "$1 has $(grep "^[[:space:]]*$" $1|wc -l) blank lines." else eho "no blank lines" fi #!/bin/bash # if [ $(id -u $1) -eq 0 ];then echo "admin" elif[ $(id -u $1) -le 500 ];then echo "common user" else echo "system user" fi #if后面只是测试条件 测试条件:命令;命令是会被执行的,把执行的结果发送的>/dev/null ;系统会自动获得命令的执行状态返回值,状态返回值为0则说明条件满足了。非0则说明条件不满足。 测试条件:比较表达式。[ 比较内容 ],中括号两边要有空格。
2)case语句
有多个测试条件时,case语句会使的语法格式更明细。
case 变量引用 in PATTERN1) 分支1 ;; PATTERN2) 分支2 ;; .... *) 分支n ;; esac PATTERN:类同于文件名统配,支持使用|表示或者。 a|b: a或者b *:匹配任意长度的任意字符 ?:匹配任意单个字符 []:指定范围内的任意单个字符。
#!/bin/bash
#
read -p "Plz enter a char: " char #输入一个字符
case $char in
[0-9]) #判断是否为数字
echo "a digit"
;;
[a-z]) #判断是否为字母
echo "a char"
;;
*)
echo "a special word" #其他显示special Word
;;
esac
八:循环语句
for循环语句
for语句的格式:
for VAR_NAME in LIST
do
循环体
done
LIST:列表,中间包括一个或多个元素
1:可以是 {起始值..结束值} 2:可以使用`seq 起始值 结束值` 或$(seq 起始值 结束值) 3:还可以是命令(命令的执行可以得到一个列表)
退出条件:遍历结束
注意:for循环的条件是变量在列表中可以取到值,否则将不执行 循环体语句,同样for循环也可以嵌套使用
for userNo in $(seq 1 5); do #LIST为1-5个元素
useradd user${userNo} #添加用户user-user5
done
while循环语句
while语句的格式:
while 测试条件; do #测试条件为真执行一次循环,退出条件为测试条件为假。
循环体 #在循环体重不断改变着测试条件。
done
#!/bin/bash #求100以内所有整数的和
declare -i count=1
declare -i sum=0
while [ $count -le 100 ]; do #count的值小于等于100时执行下面的循环(为真执行)
let sum+=$count
let count++
done
echo $sum
注意
1:while循环是在条件满足时进入循环,当条件不满足时退出循环体
2:循环体中须有让循环体自动的去判断条件语句的条件,否则循环将陷入死循环或者达不到我们预期的目的
3:条件可以是个命令或者条件表达式
until循环语句
until语句的格式:
until 测试条件; do #测试条件为假时进入循环。
循环体
done
#!/bin/bash #求100以内所有整数的和
declare -i count=1
declare -i sum=0
until [ $count -gt 100 ]; do #count的值大于100时不执行执行下面的循环(为真不执行)
let sum+=$count
let count++
done
echo $sum
for 循环 中循环的内容要先生成然后保存到内存当中。对于大量的循环条件,要占用很多的内存。
对于具体数字提前未知时,不便用for来来进行循环
while 和until 必须要有退出条件
break语句和continue语句
循环控制:
continue: 提前进入下一轮循环
用于条件语句中,仅在某些个特殊场景提前进入;
break [n]:跳出当前循环
用于条件语句中,
#!/bin/bash # sum=0 for i in {1..100};do if [ $[$i%3] -ne 0 ];then continue #符合条件跳出循环。 fi let sum+=$i done echo $sum #!/bin/bash # read -p "PlZ enter a username: " userName #提示输入一个用户 while true; do #while ture 始终为真一直循环 if who | grep "\<$userName\>" &> /dev/null; then #如果用户来了执行break跳出循环 break fi echo "not here." #否则一直显示user not here sleep 5 # 睡5s执行一次循环 done echo "$userName is logged on."
函数
形式一
function F_NAME {
函数体
}
形式二
F_NAME() {
函数体
}
#/bin/bash # dirName=/tmp/test function createDir { #定义函数为createDir if [ -d $dirName ];then echo "$dirName exits" else make $dirName echo "Create $dirName" fi } function main { #定义函数在定义成main函数 createDir createDir } 可调用:使用函数名进行调用,函数名出现的地方,会被自动替换为函数; 函数的返回值: 函数的执行结果返回值:代码的输出 函数中的打印语句:echo, print 函数中调用的系统命令执行后返回的结果 执行状态返回值:函数的代码片段是否执行成功。 函数体中最后一次执行的命令状态结果 自定函数执行状态的返回值:return # 函数可以接受参数: 在函数体中调用函数参数的方式同脚本中调用脚本参数的方式:位置参数 $1, $2, ... $#, $*, $@
信号捕捉trap
trap 'COMMAND' SIGNALE ; SIGINT
变量赋值操作
${variable:-string}
variable为空或未设定,那么返回string,否则,返回variable变量的值;
${variable:=string}
variable为空或未设定,则返回string,且将string赋值给变量variable,否则,返回variable的值;