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

  

posted @ 2019-10-15 11:40  筱筱的小孩  阅读(156)  评论(0)    收藏  举报