操作系统内核(kernel)与shell是独立的套件,而且都可被替换: 不同的操作系统使用不同的shell; 同一个kernel之上可以使用不同的shell。
一.Shell脚本解释器
Linux的Shell脚本解释器种类众多,一个系统可以存在多个shell脚本解释器,可以通过cat /etc/shells 命令查看系统中安装的shell脚本解释器。
1 [root@localhost shell]# cat /etc/shells 2 /bin/sh 3 /bin/bash 4 /usr/bin/sh 5 /usr/bin/bash
bash由于易用和免费,在日常工作中被广泛使用。同时,Bash也是大多数Linux系统默认的Shell脚本解释器。
二.shell 脚本的执行方式
1 [root@localhost shell]# echo "helloworld" 2 helloworld
第一个shell脚本
创建 helloworld.sh文件
1 [root@localhost shell]# cat helloworld.sh 2 #!/bin/bash 3 echo "helloworld" 4 [root@localhost shell]# chmod +x helloworld.sh //赋予执行权限 ,如果使用sh命令方式执行,可以省略 5 [root@localhost shell]# ./helloworld.sh 6 helloworld
1 输入脚本的绝对路径或相对路径
/root/helloworld.sh
./helloworld.sh
2 bash或sh +脚本
bash helloworld.sh
sh helloworld.sh
source helloworld.sh
三.变量
语法格式:变量名=变量值
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头。 (2)等号两侧不能有空格 (3)变量名称一般习惯为大写 (4)双引号和单引号有区别,双引号仅将空格脱意,单引号会将所有特殊字符脱意 案例 STR=“hello world” A=8 定义变量A unset A 撤销变量A readonly B=2 声明静态的变量B=2,不能unset export变量名 可把变量提升为全局环境变量,可供其他shell程序使用
[root@localhost shell]# A=8
[root@localhost shell]# echo $A
8
将一个命令的执行结果赋给变量 A=`ls -la` 反引号,运行里面的命令,并把结果返回给变量A A=$(ls -la) 等价于反引号
设置环境变量 1)基本语法: export 变量名=变量值 (功能描述:设置环境变量的值) echo $变量名 (功能描述:查询环境变量的值) source 配置文件 (功能描述:让修改后的配置信息立即生效) 2)案例: 在/etc/profile 文件中定义 JAVA_HOME 环境变量 export JAVA_HOME=/opt/module/jdk1.7.0_79 export PATH=$PATH:$JAVA_HOME/bin
查看环境变量
[root@localhost shell]# echo $PWD
/root/shell
四.参数传递
在执行Shell脚本时,可以向脚本传递参数。脚本内获取参数的格式为:$n。n代表一个数字,1为执行脚本的第一个参数,2为执行脚本的第二个参数,以此类推…
$0 表示当前脚本名称。
1.修改helloworld.sh为
1 #!/bin/bash 2 echo $1 3 echo $2 4 echo $3
2.执行携带参数
1 [root@centos6-1 ~]# ./helloworld.sh haha wowow nini 2 haha 3 wowow 4 nini 5 [root@centos6-1 ~]#
五.位置参数变量
$n (功能描述:n 为数字,$0 代表命令本身,$1-$9 代表第一到第九个参数,十以上
的参数,十以上的参数需要用大括号包含,如${10})
$* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
$@ (功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)
$# (功能描述:这个变量代表命令行中所有参数的个数)
$? (功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明
上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则
证明上一个命令执行不正确了。)
$$ (功能描述:当前进程的进程号(PID))
$! (功能描述:后台运行的最后一个进程的进程号(PID))
[root@localhost shell]# cat position.sh #!/bin/bash echo "$1" echo "$2" echo "$*" echo "$@" echo "$#" [root@localhost shell]# ./position.sh 10 20 10 20 10 20 10 20 2
[root@localhost shell]# cat position1.sh #!/bin/bash echo "$$" ./helloworld.sh & echo "$!" echo "$?" [root@localhost shell]# ./position1.sh 1751 1752 0
六.Shell字符串
单引号字符串中不支持引用变量,任何字符都会原样输出,单引号会将所有特殊字符脱意
单引号字串中不能出现单引号(对单引号使用转义符后也不行)
双引号里可以引有变量,双引号里支持转义字符
1 [root@localhost shell]# name='my name is zaomianbao'; echo $name 2 my name is zaomianbao 3 [root@localhost shell]# name_again="\"${name}\""; echo $name_again //经过转义 4 "my name is zaomianbao" 5 [root@localhost shell]# name_again="${name}"; echo $name_again //不经过转义 6 my name is zaomianbao
7 [root@localhost shell]# echo ${#name} //字符串长度
8 21
七.shell数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的一般形式为:
array_name=(value1 … valuen)
1 //第一数组 2 [root@centos6-1 ~]# usernames=(1 2 33 44 adsd1) 3 //默认读取第一个 4 [root@centos6-1 ~]# echo ${usernames} 5 1 6 //读取下标为0的 7 [root@centos6-1 ~]# echo ${usernames[0]} 8 1 9 //读取下标为1的 10 [root@centos6-1 ~]# echo ${usernames[1]} 11 2 12 //读取所有 13 [root@centos6-1 ~]# echo ${usernames[*]} 14 1 2 33 44 adsd1 15 //同样是读取所有 16 [root@centos6-1 ~]# echo ${usernames[@]} 17 1 2 33 44 adsd1 18 //获取数组长度 19 [root@centos6-1 ~]# echo ${#usernames[@]} 20 5 21 //同样可以获取数组长度 22 [root@centos6-1 ~]# echo ${#usernames[*]} 23 5
八.shell运算符
Shell和其他编程语音一样,支持包括:算术、关系、布尔、字符串等运算符。
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。expr 是一款表达式计算工具,使用它能完成表达式的求值操作
基本语法:
(1)“$((运算式))”或“$[运算式]” 推荐
(2)expr m + n , 注意 expr 运算符间要有空格
1.算术运算符
+ 加法
- 减法
* 乘法
/ 除法
% 模,即取余
Last login: Sun Mar 1 21:41:40 2020
[root@localhost ~]# a=10
[root@localhost ~]# b=20
[root@localhost ~]# var=$[$a+$b];echo $var
30
[root@localhost ~]# var=$[$a-$b]; echo $var
-10
[root@localhost ~]# var=$[$a * $b]; echo $var
200
[root@localhost ~]# var=$[$b / $a]; echo $var
2
[root@localhost ~]# var=$[$b % $a]; echo $var
0
[root@localhost ~]#
2.关系运算符
-eq EQUAL等于
-ne NOT EQUAL不等于
-gt GREATER THAN大于
-lt LESS THAN小于
-ge GREATER THAN OR EQUAL 大于等于
-le LESS THAN OR EQUAL 小于等
1 #!/bin/bash 2 3 a=10 4 b=20 5 6 if [ $a -eq $b ] 7 then 8 echo "$a -eq $b : a 等于 b" 9 else 10 echo "$a -eq $b: a 不等于 b" 11 fi 12 if [ $a -ne $b ] 13 then 14 echo "$a -ne $b: a 不等于 b" 15 else 16 echo "$a -ne $b : a 等于 b" 17 fi 18 if [ $a -gt $b ] 19 then 20 echo "$a -gt $b: a 大于 b" 21 else 22 echo "$a -gt $b: a 不大于 b" 23 fi 24 if [ $a -lt $b ] 25 then 26 echo "$a -lt $b: a 小于 b" 27 else 28 echo "$a -lt $b: a 不小于 b" 29 fi 30 if [ $a -ge $b ] 31 then 32 echo "$a -ge $b: a 大于或等于 b" 33 else 34 echo "$a -ge $b: a 小于 b" 35 fi 36 if [ $a -le $b ] 37 then 38 echo "$a -le $b: a 小于或等于 b" 39 else 40 echo "$a -le $b: a 大于 b" 41 fi
执行
1 [root@centos6-1 ~]# ./helloworld.sh 2 10 -eq 20: a 不等于 b 3 10 -ne 20: a 不等于 b 4 10 -gt 20: a 不大于 b 5 10 -lt 20: a 小于 b 6 10 -ge 20: a 小于 b 7 10 -le 20: a 小于或等于 b 8 [root@centos6-1 ~]#
3.布尔运算符
&& 与
|| 或
1 #!/bin/bash 2 3 a=10 4 b=20 5 6 if [[ $a -lt 100 && $b -gt 100 ]] 7 then 8 echo "返回 true" 9 else 10 echo "返回 false" 11 fi 12 13 if [[ $a -lt 100 || $b -gt 100 ]] 14 then 15 echo "返回 true" 16 else 17 echo "返回 false" 18 fi
执行
1 [root@centos6-1 ~]# ./helloworld.sh 2 返回 false 3 返回 true 4 [root@centos6-1 ~]#
按照文件权限进行判断
-r 有读的权限
-w 有写的权限
-x 有执行的权限
按照文件类型进行判断
-f 文件存在并且是一个常规的文件
-e 文件存在
-d 文件存在并是一个目录
九.流程控制
1.if语法
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
1 [root@localhost shell]# cat if.sh 2 #!/bin/bash 3 read -p "please input your name:" NAME 4 if [ $NAME == root ] 5 then 6 echo "hello ${NAME}, welcome !" 7 elif [ $NAME == tom ] 8 then 9 echo "hello ${NAME}, welcome !" 10 else 11 echo "get out here !" 12 fi 13 [root@localhost shell]# ./if.sh 14 please input your name:tom 15 hello tom, welcome ! 16 [root@localhost shell]# ./if.sh 17 please input your name:dfdff 18 get out here ! 19 [root@localhost shell]#
2.case语法:
case $变量名 in
"值 1")
如果变量的值等于值 1,则执行程序 1
;;
"值 2")
如果变量的值等于值 2,则执行程序 2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
[root@localhost shell]# cat case.sh #!/bin/bash case $1 in start) echo "starting" ;; stop) echo "stoping" ;; *) echo "Usage:{start|stop}" esac [root@localhost shell]# ./case.sh start starting [root@localhost shell]# ./case.sh stop stoping [root@localhost shell]# ./case.sh stopfdff Usage:{start|stop} [root@localhost shell]#
取值后面必须为关键字 in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。;; 与其他语言中的 break 类似,意思是跳到整个 case 语句的最后。取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
3.for语法
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
1 [root@localhost shell]# cat for.sh 2 #!/bin/bash 3 4 sum=0 5 for((i=1;i<=100;i++)) 6 do 7 sum=$(($sum + $i)) 8 done 9 echo 'sum='$sum 10 [root@localhost shell]# ./for.sh 11 sum=5050 12 [root@localhost shell]#
4.while语法
while [ 条件判断式 ]
do
程序
done
注意事项:(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
[root@localhost shell]# cat while.sh
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]
do
sum=$(($sum + $i))
i=$(($i + 1))
done
echo 'sum='$sum
[root@localhost shell]# ./while.sh
sum=5050
基本语法:
read(选项)(参数)
选项:-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)。
参数
变量:指定读取值的变量名
[root@localhost shell]# read -p "please input your name:" NAME please input your name:LIUYI [root@localhost shell]# echo $NAME LIUYI
十一.系统函数
1)basename 基本语法
basename [pathname] [suffix]
basename [string] [suffix] (功能描述:basename 命令会删掉所有的前缀包括最后一
个(‘/’)字符,然后将字符串显示出来。
选项:
suffix 为后缀,如果 suffix 被指定了,basename 会将 pathname 或 string 中的 suffix 去掉。 案例
[root@localhost shell]# basename /root/shell/helloworld.sh helloworld.sh [root@localhost shell]# basename /root/shell/helloworld.sh .sh helloworld
2)dirname 基本语法
dirname 文件绝对路径 (功能描述:从给定的包含绝对路径的文件名中去除文件名
(非目录的部分),然后返回剩下的路径(目录的部分)) 案例
[root@localhost shell]# dirname /root/shell/helloworld.sh
/root/shell
十二.函数
函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高。像其他编程语言一样,Shell 也支持函数。Shell 函数必须先定义后使用。
1 #!/bin/bash 2 3 demoFun(){ 4 echo "这是我的第一个 shell 函数!" 5 } 6 echo "-----函数开始执行-----" 7 demoFun 8 echo "-----函数执行完毕-----"
执行
1 [root@centos6-1 ~]# ./helloworld.sh 2 -----函数开始执行----- 3 这是我的第一个 shell 函数! 4 -----函数执行完毕----- 5 [root@centos6-1 ~]#
十三.awk分割用法(默认按空格分割,如果需要指定后面跟参数 -F)
[root@localhost shell]# df -h | awk '{print $1 "\t" $2 "\t" $3}' Filesystem Size Used devtmpfs 484M 0 tmpfs 496M 0 tmpfs 496M 6.8M tmpfs 496M 0 /dev/mapper/centos-root 6.7G 5.1G /dev/sda1 497M 157M /dev/dm-3 10G 257M tmpfs 100M 0 [root@localhost shell]#
[root@localhost shell]# cat /etc/passwd | awk -F: '{print $1 "\t" $2 "\t" $3}' root x 0 bin x 1 daemon x 2 adm x 3
十四.定时 crontab -e
十五. 追加错误日志
[root@localhost ~]# cat t2.sh #!/bin/bash pwd pxxx [root@localhost ~]# bash t2.sh >c.log 2>&1 [root@localhost ~]# cat c.log /root t2.sh: line 3: pxxx: command not found [root@localhost ~]#