shell
shell
Shell 是一个应用程序,它连接了用户和 Linux 内核,让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。然而Shell本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序,但是 Shell 也有着它的特殊性,就是开机立马启动,并呈现在用户面前;用户通过 Shell 来使用 Linux,不启动 Shell 的话,用户就没办法使用 Linux。
Shell 也是一种脚本语言,是系统命令的集合,可以使用逻辑判断、循环等语法,可以自定义函数,我们编写完源码后不用编译,直接运行源码即可。
Shell脚本是在Linux的shell中运行的,所以称为shell脚本。本质上,shell脚本就是一些命令的集合。shell脚本可以实现自动化运维,所以能帮助我们很方便的管理服务器;比如我们可以指定一个任务计划,定时的去执行某个shell脚本已满足需求。
一、shell脚本结构与执行
1.脚本结构
第一行一定是:#! /bin/bash。该命令说明,该文件使用的是bash语法,如果不设置该行,则该脚本不会被执行。以#开头的行作为解释说明。Shell脚本通常以sh为后缀,用于区分这是一个shell脚本。
编写脚本,命令如下:
[root@localhost ~]# mkdir shell
[root@localhost ~]# cd shell
[root@localhost shell]# vi 1.sh //写入如下内容
#!/bin/bash
touch /tmp/1.txt
chmod 600 /tmp/2.txt
mv /tmp/1.txt /tmp/2.txt
2.脚本执行
执行编写的脚本,命令如下:
[root@localhost shell]# ./1.sh
-bash: ./1.sh: Permission denied
[root@localhost shell]# chmod +x 1.sh //赋予权限
[root@localhost shell]# ./1.sh //执行脚本
二、shell脚本中的变量
在shell脚本中使用变量可以节省时间并且使我们的脚本更加专业,所以当我们编写一个脚本时,就可以使用变量来代替某个使用频繁并且长度很长的字符串。变量的格式:“变量名=变量的值”。
1.引用命令的结果
当我们引用某个命令的结果时,可以使用变量替代,示例如下:
[root@localhost ~]# a=`date +%w` #将命令结果赋值给变量
[root@localhost ~]# echo $a
6
[root@localhost ~]# a=$(date +%w) #将命令结果赋值给变量
[root@localhost ~]# echo $a
6
由上例可知,如果我们需要将命令结果赋值给变量,可以采用示例中两种形式的其一来实现。
2.与用户交互
示例如下:
[root@localhost ~]# read -p "请输入一个数字:" n
请输入一个数字:10
[root@localhost ~]# echo $n
10
[root@localhost ~]# read -p "请输入一个数字:"
请输入一个数字:100
[root@localhost ~]# echo $REPLY
100
3. 内置变量
示例如下:
[root@localhost shell]# vi bian.sh #创建一个名为bian.sh的脚本
[root@localhost shell]# cat bian.sh
#!/bin/bash
echo "\$1=$1"
echo "第二个参数是$2"
echo "第三个参数是$3"
echo "本脚本一共有$#个参数"
echo "\$0是$0"
[root@localhost shell]# sh bian.sh #执行脚本
$1=
第二个参数是
第三个参数是
本脚本一共有0个参数
$0是bian.sh
[root@localhost shell]# sh bian.sh a b #再次执行脚本
$1=a
第二个参数是b
第三个参数是
本脚本一共有2个参数
$0是bian.sh # $0就是脚本的名字
4.数学运算
shell脚本中的变量常用于数学运算当中,示例如下:
[root@localhost shell]# vi sum.sh #创建一个名为sum.sh的脚本
[root@localhost shell]# cat sum.sh
#!/bin/bash
a=1
b=2
sum=$[$a+$b] #还可以采用sum=$(($a+$b))这种写法
echo "$a+$b=$sum"
[root@localhost shell]# sh sum.sh #执行脚本
1+2=3
三、shell中的逻辑判断
1.不带有else
基础结构:
if 判断语句; then
command
fi
示例如下:
[root@localhost shell]# vi if1.sh
[root@localhost shell]# cat if1.sh
#!/bin/bash
a=10
if [ $a -gt 4 ]
then
echo ok
fi
[root@localhost shell]# sh -x if1.sh #执行脚本
+ a=10
+ '[' 10 -gt 4 ']'
+ echo ok
ok
[root@localhost shell]# sh -n if1.sh
2.带有else
基础结构:
if 判断语句 ; then
command
else
command
fi
示例如下:
[root@localhost shell]# vi if2.sh
[root@localhost shell]# cat if2.sh
#!/bin/bash
a=10
if [ $a -gt 4 ]
then
echo ok
else
echo "not ok"
fi
[root@localhost shell]# sh -x if2.sh #执行脚本
+ a=10
+ '[' 10 -gt 4 ']'
+ echo ok
ok
3.带有elif
示例如下:
[root@localhost shell]# vi if3.sh
[root@localhost shell]# cat if3.sh
#!/bin/bash
a=3
if [ $a -gt 4 ]
then
echo ok
elif [ $a -gt 8 ]
then
echo "very ok"
else
echo "not ok"
fi
[root@localhost shell]# sh -x if3.sh #执行脚本
+ a=3
+ '[' 3 -gt 4 ']'
+ '[' 3 -gt 8 ']'
+ echo 'not ok'
not ok
4.嵌套
示例如下:
[root@localhost shell]# vi if4.sh
[root@localhost shell]# cat if4.sh
#!/bin/bash
a=10
if [ $a -gt 4 ]
then
if [ $a -lt 20 ]
then
echo "ok"
else
echo "very ok"
fi
else
echo "not ok"
fi
[root@localhost shell]# sh -x if4.sh #执行脚本
+ a=10
+ '[' 10 -gt 4 ']'
+ '[' 10 -lt 20 ']'
+ echo ok
ok
四、 shell中的循环
1.for循环
基础结构如下:
for 变量名 in 循环条件;
do
command
done
下面进行一个简单的实验演示,演示如下:
[root@localhost shell]# vi for1.sh
#!/bin/bash
sum=0
for i in `seq 1 10`
do
sum=$[$sum+$i]
echo $i
done
echo $sum
执行结果:
2.while循环
基础结构:
while 条件; do
command
done
示例1:
[root@localhost shell]# vi while1.sh
#!/bin/bash
while : #此处冒号表示死循环
do
load=`w|head -1|awk -F 'load average:' '{print $2}'|cut -d. -f1` #赋值给变量load
if [ $load -gt 10 ]
then
top|mail-s "load is high: $load" asldkfls011.com
fi
sleep 30
done
运行结果:
示例2:
[root@localhost shell]# vi while2.sh #创建一个脚本
#!/bin/bash
while :
do
read -p "Please input a number: " n
if [ -z "$n" ]
then
echo "you need input sth."
continue
fi
n1=`echo $n|sed 's/[0-9]//g '`
if [ -n "$n1" ]
then
echo "you just only input numbers."
continue
fi
break
done
cho $n
运行结果:
五、 shell中的中断与继续
1.跳出循环
break在脚本中表示跳出该层循环,示例如下:
[root@localhost shell]# vi break1.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
break
fi
echo $i
done
echo aaaaa
执行结果:
2.结束本次循环
当在shell脚本中使用continue时,结束的不是整个循环,而是本次循环。忽略continue之下的代码,直接进行下一次循环。示例如下:
[root@localhost shell]#vi continue1.sh #创建一个shell脚本
#!/bin/bash
for i in `seq 1 5 `
do
echo $i
if [ $i == 3 ]
then
continue #此处continue表示若 $i == 3 则结束本次循环
fi
echo $i
done
echo $i
执行结果:
3. 退出整个脚本
当我们在shell脚本中遇到exit时,其表示直接退出整个shell脚本。示例如下:
[root@localhost shell]# vi exit1.sh
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i == 3 ]
then
exit
fi
echo $i
done
echo aaaa
执行结果:
六、shell中的函数
shell脚本中的函数就是先把一段代码整理到了一个小单元中,并给这个小单元命名,当我们用到这段代码时直接调用这个小单元的名字就可以了,这样很方便,省时省力。但我们需要注意,在shell脚本中,函数一定要写在前面,因为函数要被调用的,如果还未出现就被调用就会出错。
基础格式:
function f_name()
{
command
}
1.打印出第一个、第二个参数、参数的个数及脚本名
示例如下:
[root@localhost shell]# vi fun1.sh
#/bin/bash
input()
{
echo $1 $2 $# $0 # 函数的参数:$1 $2 $# ;$0则是脚本的名字
}
input 1 a b
执行结果:
2.加法的函数
示例如下:
[root@localhost shell]# vi fun2.sh
#!/bin/bash
sum()
{
s=$[$1+$2]
echo $s
}
sum 1 2
执行结果:
3.获得一个网卡的IP地址
示例如下:
[root@localhost shell]# vi fun3.sh
#!/bin/bash
ip()
{
ifconfig |grep -A1 "$1: " |tail -1 |awk '{print $2}'
}
read -p "Please input the eth name: " e
myip=`ip $e`
echo "$e address is $myip"
执行结果:
七、shell中的数组
1.数组读取
首先我们需要先定义一个数组a=(1 2 3 4 5);
命令 echo ${a[@]} 读取数组中的全部元素。示例如下:
命令 echo ${#a[@]} 获取数组的元素个数。示例如下:
命令 echo ${a[2]} 读取第三个元素,数组从0开始。示例如下:
echo ${a[*]} 等同于 ${a[@]} 作用为显示整个数组。示例如下:
2.数组赋值
a[1]=100; echo ${a[@]} 替换指定的元素值。示例如下:
a[5]=2; echo ${a[@]} 如果下标不存在则会自动添加一个元素。示例如下:
a[7]=6; echo ${a[@]} 跳着添加元素时,中间未赋值的元素,不显示且无值。示例如下:
3.数组的删除
命令unset a[1] 用于删除单个元素。示例如下:
命令unset a 用于删除整个数组。示例如下:
4.数组分片
在进行实验操作之前,需要对一个数组进行赋值 a=(`seq 1 5`) 。
命令echo ${a[@]:0:3} 表示从第一个元素开始,截取3个元素,并打印出来。示例如下:
命令echo ${a[@]:1:4} 表示从第二个元素开始,截取4个元素,并打印出来。示例如下:
echo ${a[@]:0-3:2} 表示从倒数第3个元素开始,截取2个元素,并打印出来。示例如下:
5.数组替换
使用命令echo ${a[@]/b/100} 表示用100替换b,但不会保存替换,只是打印出来。示例如下:
使用命令a=(${a[@]/b/100}) 表示用100替换b,这种方法不仅可以打印出来还可以保存替换。示例如下: