前言:基础
Centos默认的脚本解析器是bash(bash也是软连接文件sh -> bash)
脚本第一行声明bash脚本:#!/bin/bash
脚本执行
1、sh+脚本名称
2、给脚本赋予权限chmod u+x 脚本名称
,绝对路径and相对路直接径运行
脚本环境准备
修改vimrc文件,达到控制vim创建,编辑文件的动作
- 当前用户家目录下 ~/.vimrc
- 放在/etc/vimrc
" 2024/*/*新增,编辑sh文件默认开头
set ignorecase
autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"
func SetTitle()
if expand("%:e") == 'sh'
call setline(1, "#!/bin/bash")
call setline(2, "##############################################################")
call setline(3, "# File Name:".expand("%"))
call setline(4, "# Version:V1.0")
call setline(5, "# Author: shishuwu")
call setline(6, "# Organization: GTS")
call setline(7, "# Desc:")
call setline(8, "##############################################################")
call setline(9, " ")
endif
endfunc
一、变量
需要sorce /etc/profile
和sorce ~/.bashrc
重新加载环境变量
printenv
输出当前环境变量
1、全局变量 /etc/profile
2、局部变量~/.bashrc
3、定义自定义变量export Su7=21.69
,输出变量 echo $Su7
1、关于自定义变量
记住:用户登录之后开启一个解释器bash(-号),当启动一个脚本文件;重新启动一个bash(二号)去执行脚本,二号bash是一号子bash。
[shishu@hadoop1]$ export B=su7
[shishu@hadoop1]$ echo $B
[shishu@hadoop1]$ cat helloworld.sh
echo "helloworld'
echo $B
[shishu@hadoop1]$ sh helloworld.sh
helloword
su7
如果再去开一个窗口,就意味着开了一个新的bash,不能继承这个同级别的bash变量。
2、特殊变量 $
和 $#
$n
功能描述:n为数字,$0
代表该脚本名称,$1-$9
代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}
$#
传参数个数
[root@clb1 shell]# cat teshu.sh
#!/bin/bash
#传参个数
echo $#
#参数输出
echo "$0 $1 $2"
[root@clb1 shell]# sh teshu.sh xiaomi su7
2
teshu.sh xiaomi su7
3、特殊变量 $*
和 $@
$*
功能描述:这个变量代表命令行中所有的参数,$*
把所有的参数看成一个整体
$@
功能描述:这个变量也代表命令行中所有的参数,不过$@
把每个参数区分对待
4、特殊变量 $?
$?
功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个$?
变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。
echo $?
二、数学计算
#!/bin/bash
A=100
B=2
#第一种写法
C=$((A+B))
#第二种
D=$[A+B]
#第三种
E=`expr $A + $B`
echo $E
#综合运算(2+3)*5
F=$[(2+3)*5]
#expr `expr 2+3` * 5
echo $F
三、条件判断
1、常用判断条件
(1) 两个整数之间比较
- = 字符串比较
- -lt 小于(less than)
- -le 小于等于(less equal)
- -eq 等于(equal)
- -ne 不等于(Not equal)
- -gt 大于(greater than)
- -ge 大于等于(greater equal)
(2) 按顺文件权限进行判断
-r 有读的权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)
(3) 按顺文件关型进行判断
-f 文件存在并且是一个常规的文件(file)
-e 文件存在(existence)
-d 文件存在并是一个目录(directory)
2 、练习实操
(1) 逻辑语句 &&
和 ||
&&
前面条件成立,后面语句才会执行(逻辑与)
||
前面条件不成立,后面语句才会执行(逻辑或)
[root@clb1 shell]# cat luoji.sh
#!/bin/bash
#&& 逻辑与 和 逻辑或
echo $#
[ $# -gt 2 ] && echo "参数的个数大于2"
[ $# -lt 2 ] || echo "参数的个数大于2----"
[root@clb1 shell]# sh luoji.sh 1 2 3
3
参数的个数大于2
参数的个数大于2----
[root@clb1 shell]# sh luoji.sh 1 2
2
参数的个数大于2----
[root@clb1 shell]# sh luoji.sh 1
1
(2) 利用命令的执行结果进行判断
判断用户是否存在,创建用户
参考:echo $?
输出的0 和 1 ,表示Y 与 F
#!/bin/bash
#如果用户zhangsan不存在,则添加用户zhangsan
id zhangsan &> /dev/null && echo "zhangsan用户存在,不用添加"
id zhangsan &> /dev/null || useradd zhangsan
四、流程控制
1、if 判断
基本格式
注意事项: (1) [ 条件判断式 ],中括号和条件判断式之间必须有空格
(2) if后要有空格
if [ 条件判断句 ];then
程序
fi
#或者
if [ 条件判断句 ]
then
程序
fi
案例:判断年龄
[root@clb1 shell]# cat if.sh
#!/bin/bash
if [ $1 -lt 18 ];then
echo "未成年"
elif [ $1 -ge 18 -a $1 -le 30 ];then
echo "青年"
else
echo "中老年"
fi
[root@clb1 shell]# sh if.sh 22
青年
[root@clb1 shell]# sh if.sh 33
中老年
[root@clb1 shell]# sh if.sh 3
未成年
2、case语句
基本格式
注意事项
1)case行尾必须为单词“in",每一个模式匹配必须以右括号
)
结束2)双分号
;;
表示命令序列结束,相当于java中的break。3)最后的
*)
表示默认模式,相当于java中的default。
case $变量名 in
“值1”)
如果变呈的值等于值1,则执行程序1
;;
“值2”)
如果变星的值等于值2,则执行程序2
;;
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
案例:判断输入
[root@clb1 shell]# cat case.sh
#!/bin/bash
case $1 in
"start")
echo "你输入的是start"
;;
"stop")
echo "你输入的是stop"
;;
*)
echo "你输入的是其他"
;;
esac
[root@clb1 shell]# sh case.sh stop
你输入的是stop
[root@clb1 shell]# sh case.sh start
你输入的是start
[root@clb1 shell]# sh case.sh st
你输入的是其他
3、for 循环
(1) 用法一
基础语法
for ((初始值;循环控制条件;变量变化))
do
程序
done
案例:1到100的和
#!/bin/bash
for ((i=0;i<=100;i++));do
s=$[$s+$i]
done
echo "1到100的和是$s"
(2) 用法二
基础语法
for 变量 in 值1 值2 值3...
do
程序
done
案例 1:1到100的和
[root@clb1 shell]# cat sum100.2.sh
#!/bin/bash
for i in {1..100};do
s=$[$s+$i]
done
echo "1到100的和是$s"
[root@clb1 shell]# cat sum100.2.sh
#!/bin/bash
for i in `seq 1 100`;do
s=$[$s+$i]
done
echo "1到100的和是$s"
案例 2:显示/root下面所有文件名称
案例告诉我们,在for循环中,空格和换行都可以进行分割字符
[root@clb1 shell]# cat file.sh
#!/bin/bash
for i in `ls /root`;do
echo $i
done
案例 3:区分$*
和$@
只有$*
和$@
带上双引号代表的意义才不同
踩坑提示
echo "我是你的" echo"我是你的"
在脚本中echo后面有没有空格的含义是不一样的。
如果没有空格整个语句会被认为是一条命令。例如下面的报错
qufen.sh:行3: echo传入脚本的参数是:qqq: 未找到命令 qufen.sh:行3: echo传入脚本的参数是:www: 未找到命令 --------------
[root@clb1 shell]# cat qufen.sh
#先测试$*
for i in "$*";do
echo "传入脚本的参数是:$i"
done
echo "--------------"
#测试$@
for j in "$@";do
echo "传入脚本的参数是:$j"
done
[root@clb1 shell]# sh qufen.sh 123 321
传入脚本的参数是:123 321
--------------
传入脚本的参数是:123
传入脚本的参数是:321
4、while循环
案例 :1到100的和
[root@clb1 shell]# cat sum100.3.sh
#!/bin/bash
i=1
sum=0
while [ $i -le 100 ];do
let sum=sum+i
#这行代码也可以写成:sum=$[$sum+$i]
let i++
done
echo "从1到100的和是:$sum"
[root@clb1 shell]# bash sum100.3.sh
从1到100的和是:5050
五、read读取控制台输入
1、基础语法
read(选项)(参数)
选项:
-p:指定读取值时的提示符
-t: 指定读取值时等待的时间(秒)
参数:
变量:指定读取值的变量名
2、练习实操
案例 : 求1到输入数字的和
[root@clb1 shell]# cat sumx.sh
#!/bin/bash
read -p "请输入的数字" x
i=1
sum=0
while [ $i -le $x ];do
let sum=sum+i
let i++
done
echo "1到$x的和是$sum"
[root@clb1 shell]# sh sumx.sh
请输入的数字10
1到10的和是55
for循环
#!/bin/bash
read -t 3 -p "请在3秒内请输入的数字" x
sum=0
for ((i=1;$i<=$x;i++));do
let sum=sum+i
done
echo "1到$x的和是$sum"
六、函数
1、系统函数
(1)basename
基本语法
basename命令会删掉所有的前缀包括最后一个(/)字符
也可以指定后缀,来切除末尾
[root@clb1 shell]# basename /root/shell/sumx.sh
sumx.sh
[root@clb1 shell]# basename /root/shell/sumx.sh .sh
sumx
(2)dirname
基本语法
dirname 文件绝对路径
功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分)然后返回剩下的路径(目录的部分)
[root@clb1 shell]# dirname /root/shell/sumx.sh
/root/shell
(3)综合案例
更换txt文件为sh文件
[root@clb1 shell]# cat zhixing.sh
#!/bin/bash
i=0
for f in `ls /root/shell/*.txt`;do
basename=`basename $f .txt`
file=$basename".sh"
mv $f $file
let i++
echo "已更改$i个文件"
echo "本次已经修改源文件$f变为$file"
done
2、自定义函数
基本用法
1、必须在调用函数地方之前,先声明函数,shel脚本是逐行运行。不会像其它语言一样先编译。 2、函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)
案例练习1:自定义两数之和sum()
利用result承接输入值,利用echo $?
输出。但是return后跟数值n(0-255)有范围,所以建议用下面优化版本。
[root@clb1 shell]# cat zidingyi.1.sh
#!/bin/bash
#自定义函数
function sum(){
let s=$1+$2
return $s
}
sum 100 200
echo $?
[root@clb1 shell]# sh zidingyi.1.sh
44
[root@clb1 shell]# cat zidingyi.2.sh
#!/bin/bash
#自定义函数
function sum(){
let s=$1+$2
return $s
}
sum 10 200
echo $?
[root@clb1 shell]# sh zidingyi.2.sh
210
优化版本
[root@clb1 shell]# cat zidingyi.3.sh
#!/bin/bash
#自定义函数
function sum(){
let s=$1+$2
echo $s
}
result=`sum 100 200`
echo $result
[root@clb1 shell]# sh zidingyi.3.sh
300
案例练习2:求数据的阶乘
[root@clb1 shell]# cat jiecheng.sh
#!/bin/bash
if [ $1 -eq 1 ];then
echo "参数错误,程序退出!"
exit 3 #返回的状态码 也就是echo #?输出的
fi
function jiecheng(){
n=$1
if [ $n -le 1 ];then
echo 1 #当n=1的时候,函数的返回值
return 0 #返回的执行状态
elif [ $n -gt 1 ];then
let pre_n=$n-1
temp=$(jiecheng $pre_n)
let result=n*temp
echo $result
return 0
fi
}
jiecheng $1
[root@clb1 shell]# sh jiecheng.sh 5
120
七、Shell工具
1、cut
[root@clb1 shell]# echo $PATH | cut -d : -f1
/usr/local/sbin
[root@clb1 shell]# grep "/bin/bash$" /etc/passwd |cut -d : -f1
root
2、awk
[root@clb1 shell]# awk -F ":" 'BEGIN{print "username,shell"} $NF ~ "/bin/bash$"{print $1","$NF} END{print "END"}' /etc/passwd
username,shell
root,/bin/bash
END