linux--shell脚本基础
1.什么是shell?
shell是用户和内核交互的桥梁,既是命令解释器,又是一种编程语言,可用于编写脚本以用于实现自动化运维的目的!
2.查看shell
查看系统支持的shell
[root@test02 ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
查看用户登入默认的shell
[root@test02 ~]# cat /etc/passwd|awk -F: '{print $1,$7}'|grep root
root /bin/bash
查看当前生效的shell [root@test02 ~]# echo $SHELL /bin/bash
3.shell变量
3.1变量的命名
可用英文字母和数字及下划线自由组合,但是不能以数字开头,等号两边不能有空格。
建议环境变量使用大写字母,自定义变量用小写字母
[root@test02 ~]# x=1 [root@test02 ~]# echo $x 1 [root@test02 ~]# var_name=zz [root@test02 ~]# echo $var_name zz [root@test02 ~]# _name=mm [root@test02 ~]# echo $_name mm [root@test02 ~]# var_1=gg [root@test02 ~]# echo $var_1 gg
3.2变量的扩增
[root@test02 ~]# var_name="$var_name":long [root@test02 ~]# echo $var_name zz:long
[root@test02 ~]# name=zz
[root@test02 ~]# echo name
name
[root@test02 ~]# str=hello
[root@test02 ~]# echo $str
hello
字符串以变量拼接
[root@test02 ~]# name=thisis$name
[root@test02 ~]# echo $name
thisiszz
[root@test02 ~]# name=${name}this
[root@test02 ~]# echo $name
zzthis
变量和变量拼接
[root@test02 ~]# name=$name$str
[root@test02 ~]# echo $name
zzhello
3.3变量拼接时有空格需用单引号或双引号
单引号时,原样输出 [root@test02 ~]# name1='this is $var_name' [root@test02 ~]# echo $name1 this is $var_name 双引号时,会输出变量的值 [root@test02 ~]# name2="this is $var_name" [root@test02 ~]# echo $name2 this is zz:long
3.4将命令的结果赋值给变量
1.方法一: [root@test02 ~]# str1=$(uname -r) [root@test02 ~]# echo $str1 3.10.0-123.el7.x86_64 2.方法二: [root@test02 ~]# str2=`uname -r` [root@test02 ~]# echo $str2 3.10.0-123.el7.x86_64
3.5删除变量,通过unset命令
[root@test02 ~]# echo $str2 3.10.0-123.el7.x86_64 [root@test02 ~]# unset str2 [root@test02 ~]# echo $str2
3.7变量的作用域
环境变量:可以在子shell中使用
全局变量:可在当前的shell中使用
局部变量:只能在函数内部使用
str在当前shell中 [root@test02 ~]# echo $str hello 进入子shell [root@test02 ~]# bash 在shell中查看不了$str变量的值 [root@test02 ~]# echo $str 退出子shell [root@test02 ~]# exit exit 使用export命令使$str全局变量变成环境变量 [root@test02 ~]# export str 进入子shell [root@test02 ~]# bash 在子shell中已可以查看到$str变量的值 [root@test02 ~]# echo $str hello
4.编写shell脚本
4.1 脚本规范
脚本名必须以 .sh 结尾,第一行固定格式 #!/bin/bash ,指明脚本的解释器,添加注释使用 # 号
[root@test02 shell]# cat hello.sh #!/bin/bash echo "Hello World!"
4.2 脚本的执行
第一张方法: sh + 脚本名字
[root@test02 shell]# sh hello.sh Hello World!
第二种方法:给脚本添加执行权限
添加执行权限
[root@test02 shell]# chmod +x hello.sh 相对路径执行
[root@test02 shell]# ./hello.sh Hello World! [root@test02 shell]# pwd /shell
绝对路径执行 [root@test02 shell]# /shell/hello.sh Hello World!
4.3 脚本的传递参数
$n :n为数字,$0代表脚本名字,$1代表第一个参数,$2代表第二个参数,以此类推
$# : 传递给脚本的所用参数的个数
$* :传递给脚本的所用参数
$@ :传递给脚本的所有参数,当被双引号包含时,与$*有区别
$? :上次一执行结果的状态,0表示无错误
$$ : 当前shell的进程ID号
[root@test02 shell]# cat scripts.sh #!/bin/bash echo "脚本名: $0" echo "第一个参数: $1" echo "第二个参数: $2" echo "传递的参数的个数为: $#" echo "传递的参数是: $@" echo "传递的参数是: $*" echo "上一次执行结果的返回值:$?" echo "上一次shellpid是: $$" [root@test02 shell]# sh scripts.sh hello world ! 脚本名: scripts.sh 第一个参数: hello 第二个参数: world 传递的参数的个数为: 3 传递的参数是: hello world ! 传递的参数是: hello world ! 上一次执行结果的返回值:0 上一次shellpid是: 6582
$@和$*区别
不加双引号时,两者没啥区别,都是把接收到的每一个参数依次输出"$1" "$2" "$3"........
[root@test02 shell]# cat temp.sh #!/bin/bash echo "print 1" for var in $@ do echo "$var" done echo "print 2" for var in $* do echo "$var" done [root@test02 shell]# sh temp.sh a b c d e print 1 a b c d e print 2 a b c d e
加双引号时,$@ 依次输出每一个接收的参数,"$1" "$2" "$3".......;$*则是把所有参数当成一个整体输出" $1 $2 $3...."。
[root@test02 shell]# cat temp.sh #!/bin/bash echo "print 1" for var in "$@" do echo "$var" done echo "print 2" for var in "$*" do echo "$var" done [root@test02 shell]# sh temp.sh a b c d e print 1 a b c d e print 2 a b c d e
5.shell字符串的截取
5.1获取字符串长度
[root@test02 shell]# cat string.sh
#!/bin/bash
str1=abcdefg
str2=qwer
echo "${#str1}"
echo "${#str2}"
[root@test02 shell]# sh string.sh
7
4
5.2截取字符串
${string:start:length}:string:为字符串 start:开始的位置(从左边开始,从0计数),length:截取的长度,省略则默认截取到到末尾,超出字符串长度则也是截取到到末尾
[root@test02 shell]# str=abcefgabc
[root@test02 shell]# echo ${str:2:3}
cef
[root@test02 shell]# echo ${str:5:3}
gab
[root@test02 shell]# echo ${str:5:20}
gabc
[root@test02 shell]# echo ${str:2}
cefgabc
反向截取
${string:0-start:length} :0-start:表示从右边开始计数,从1开始,但是截取方向还是从左到右
[root@test02 shell]# echo ${str:0-2:2}
bc
[root@test02 shell]# echo ${str:0-8:5}
bcefg
[root@test02 shell]# echo ${str:0-9:5}
abcef
[root@test02 shell]# echo ${str:0-5:3}
fga
指定字符串截取
从左向右删除,删除第一个:号及之前的字符串,使用“#”
[root@test02 shell]# echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@test02 shell]# echo ${PATH#*:}
/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
删除最后一个:号及之前的字符串,使用“##”
[root@test02 shell]# echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@test02 shell]# echo ${PATH##*:}
/root/bin
从右往左删除,删除最后一个:号及后面的字符串,使用“%”
[root@test02 shell]# echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@test02 shell]# echo ${PATH%:*bin}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
删除第一个:号及之后的字符串,使用“%%”
[root@test02 shell]# echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@test02 shell]# echo ${PATH%%:*bin}
/usr/local/sbin
6.shell数组
6.1数组的定义
数组用括号表示,元素位于括号内,用空格隔开,下标从0开始,数组中的元素类型也可以不同,数组的长度是可变的
[root@test02 shell]# array=(1 2 3 4 5) [root@test02 shell]# array2=(a b c hello_man) [root@test02 shell]# array3=(6 a Bug 23*mk_fd2)
数组的另一种定义方式,给数据增加元素也是用这种方式
[root@test02 shell]# array4[0]=1 [root@test02 shell]# array4[1]=2 [root@test02 shell]# array4[2]=3
6.2数组的读取
获取单个元素,使用下标
[root@test02 shell]# echo ${array[0]}
1
[root@test02 shell]# echo ${array2[0]}
a
[root@test02 shell]# echo ${array3[2]}
Bug
[root@test02 shell]# echo ${array3[3]}
23*mk_fd2
[root@test02 shell]# echo ${array4[1]}
2
获取所有元素,使用 * 或者 @
[root@test02 shell]# echo ${array[*]}
1 2 3 4 5
[root@test02 shell]# echo ${array[@]}
1 2 3 4 5
增加数组元素
[root@test02 shell]# array[5]=6
[root@test02 shell]# echo ${array[@]}
1 2 3 4 5 6
获取数组长度,使用 #
[root@test02 shell]# echo ${#array2[*]}
4
[root@test02 shell]# echo ${#array4[*]}
3
获取数组元素的长度
[root@test02 shell]# echo ${array2[*]}
a b c hello_man
[root@test02 shell]# echo ${array2[3]}
hello_man
[root@test02 shell]# echo ${#array2[3]}
9
6.3数组的拼接
[root@test02 shell]# arr1=(1 2 3)
[root@test02 shell]# arr2=(a c dog)
[root@test02 shell]# arr=(${arr1[*]} ${arr2[*]})
[root@test02 shell]# echo ${arr[*]}
1 2 3 a c dog
[root@test02 shell]# echo ${#arr[*]}
6
[root@test02 shell]# echo ${arr[5]}
dog
[root@test02 shell]# echo ${arr[2]}
3
6.4删除数组
删除数组元素,unset array_name[index](数组名加下标指定)
[root@test02 shell]# echo ${arr1[*]}
1 2 3
[root@test02 shell]# unset arr1[2]
[root@test02 shell]# echo ${arr1[*]}
1 2
删除数组,unset array_name
[root@test02 shell]# echo ${arr2[*]}
a c dog
[root@test02 shell]# unset arr2
[root@test02 shell]# echo ${arr2[*]}
7.设置变量属性declare
[root@test02 shell]# cat data.sh #!/bin/bash declare -i a b c a=1 b=2 c=$a+$b echo "$c" [root@test02 shell]# sh data.sh 3
-i:将a b c 声明为整数进行运算 ,若要取消变量属性使用 "+"( declare +i a b c)
declare中的选项声明
-i:声明变量为整数型
-a:声明变量为数组
-r:声明变量为只读变量(不可删除和修改)
-x:声明变量为环境变量
-g:在shell内部创建全局变量
-p:显示变量的名字和值
8.shell数学运算
8.1算术运算符
+:加法 -:减法 *:乘法 /:除法 %:取余 =:赋值 ==:判断两个数字是否相等,相等返回true !=:判断两个数字是否不相等,不相等返回true
8.2字符串运算符
=:判断两个字符串是否相等 !=:判断两个字符串是否不等 -z:判断字符串长度是否为0,为0返回true -n:判断字符串长度是否为0,不为0返回true
$:判断字符串是否为空,不为空,返回true
8.3关系运算符(用于数值判断)
-eq:判断两个是否相等(等同 == ) -ne:判断两个数是否不等( != ) -gt:判断左边是否大于右边( > ) -lt:左边是否小于右边( < )
-ge:左边是否大于等于右边( >= ) -le:左边是否小于等于右边( <= )
8.3或与非
!:非 &&:与( 和 -a 效果相同 ) ||:或 ( 和 -o 效果相同 )
8.4文件判断
-e:判断文件是否存在(包括目录) -f:判断是否是普通文件 -d:判断是否是目录 -c:判断是否是字符设备文件 -b:判断是否是块设备文件
-s:判断文件是否为空,不为空返回true -r:文件是否可读 -w:文件是否可写 -x:文件是否可执行
8.5使用 双括号 (()) 进行数学运算,只能进行整数运算,不能进行小数运算
[root@test02 shell]# a=1 [root@test02 shell]# b=2 [root@test02 shell]# c=a+b [root@test02 shell]# echo $((c)) 3
9.shell 条件语句
9.1 if 语句
if-else语句
if [ 条件 ]
then
执行语句1
else
执行语句2
fi
[root@test02 shell]# cat if.sh #!/bin/bash read -p "请输入一个动物的英文名称:" -t 20 name if [ "$name" = "dog" ];then echo "输入的动物是:狗" else echo “请输入狗的英文名称” fi
read:用于读取键盘输入,-p:后面接提示信息 -t:后面接数字,代表等待输入的时间,单位为秒
[ ]:用于判断,左右都要有一个空格,变量和引用的值最好都加双引号
if-elif-else语句
if [ 条件1 ]
then
执行语句1
elif [ 条件2 ]
then
执行语句2
elif [ 条件3 ]
then
执行语句3
....
else
执行语句
fi
[root@test02 shell]# cat elif.sh #!/bin/bash #判断$1是否是目录 if [ -d "$1" ] then echo "$1是一个目录" #判断$1是否是普通文件 elif [ -f "$1" ] then echo "$1是一个普通文件" #其他情况都是输入$1不存在 else echo "$1不存在" fi
9.2 case语句
case 变量 in
值1)
执行语句1
;;
值2)
执行语句2
;;
值3)
执行语句3
;;
....
esac
[root@test02 shell]# vim case.sh [root@test02 shell]# cat case.sh #!/bin/bash case $1 in #$1=dog时 dog) echo "输入的是狗" ;; #$1=cat时 cat) echo "输入的是猫" ;; #“*”代表$1=其他的值时,即使是空值的情况 *) echo "只能输入狗或者猫" esac
10.循环语句
求1到99的和
10.1 for in语句
for 变量 in 取值列表(可以是具体值,也可以是取值范围)
do
执行语句
done
#!/bin/bash
sum=0
for i in {1..99}
do
sum=$((sum+i))
done
echo "sum的值: $sum"
10.2 for (( ; ; ))语句
for ((表达式1;表达式2;表达式3))
do
执行语句
done
#!/bin/bash sum=0 for ((i=1;i<100;i++)) do sum=$((sum+i)) done echo "sum=$sum"
10.3 for嵌套9*9乘法
[root@test02 shell]# cat forfor.sh #!/bin/bash for ((i=1;i<10;i++)) do for ((j=1;j<=i;j++)) do #\t插入制表符,\c不换行输出,\c必须在最后,也可以用 -n 取代:echo -ne "$j*$i=$((i*j))\t" echo -e "$j*$i=$((i*j))\t\c" done #换行 echo -e " \n" done
10.4 forfor输出菱形“* ”,层数由传入$1来确定
[root@test02 shell]# cat forfor3.sh #!/bin/bash #控制上半部分的行数,由$1来确定 for ((x=0;x<$1;x++)) do #控制每行“ ”空格的个数 for ((i=x+1;i<$1;i++)) do #不换行输出 echo -n " " done #控制每行“* ”的个数 for ((j=0;j<=x;j++)) do #不换行输出,与 echo -n " "效果相同 echo -e "* \c" done #外循环,循环一次就换行 echo -e "\n" done #控制下半部分的行数 for ((x=0;x<$1-1;x++)) do for ((i=0;i<=x;i++)) do echo -n " " done for ((j=x;j<$1-1;j++)) do echo -n "* " done echo -e "\n" done
[root@test02 shell]# sh forfor3.sh 5
*
* *
* * *
* * * *
* * * * *
* * * *
* * *
* *
*
10.5 while循环
while 条件
do
执行语句
done
[root@test02 shell]# cat while.sh #!/bin/bash i=1 sum=0 while ((i < 100)) do ((sum+=i)) ((i++)) done echo "sum=$sum"
10.6 until循环
until 条件
do
执行语句
done
[root@test02 shell]# cat until.sh #!/bin/bash i=1 sum=0 until ((i > 99)) do ((sum+=i)) ((i++)) done echo "sun=$sum"
10.7 调出循环break和continue
break是调出整个循环,停止后续所有的循环
[root@test02 shell]# cat break.sh
#!/bin/bash
sum=0
for i in {1..99}
do
((sum+=i))
if ((sum>500))
then
break
fi
done
[root@test02 shell]# sh break.sh sum的值: 528
continue是跳出本次循环,后续循环继续,可见数字3并未输出,
[root@test02 shell]# cat continue.sh for i in 1 2 3 4 5 do if [ "$i" == "3" ] then continue fi echo "$i" done [root@test02 shell]# sh continue.sh 1 2 4 5
11. 函数
标准写法
function:定义函数的关键字
name():函数名
[return value]:函数的返回值,可写可不写,根据具体情况运用
function name(){
语句
[return value]
}
[root@test02 shell]# cat function.sh #!/bin/bash #创建函数 function name(){ if [ ! -e q.txt ] then echo '123456' > q.txt else cat q.txt fi } #调用函数 name
[root@test02 shell]# sh function.sh [root@test02 shell]# sh function.sh 123456
return示例,通过 "echo $?" 将return的值取出来
[root@test02 shell]# cat return.sh
#!/bin/bash
function temp(){
a=2
b=3
return $((a+b))
}
temp
echo $?
[root@test02 shell]# sh return.sh
5


浙公网安备 33010602011771号