(一)shell 脚本基础
观看视频:https://www.bilibili.com/video/BV14L4y157Bv/?spm_id_from=333.999.0.0
介绍
shell 是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。shell 还是一个功能强大的编程语言,易编写、易调试、灵活性强。
第一行的作用
#!/bin/bash
Shebang 在计算机程序中,shebang 指的是出现在文本文件的第一行前两个字符 #!
- 以 #!/bin/sh 开头的文件,程序在执行的时候会调用 /bin/sh,也就是 bash 解释器
- 以 #!/usr/bin/python 开头的文件,代表指定 Python 解释器去执行
- 以 #!/usr/bin/env 解释器名称,是一种在不同平台上都能正确找到解释器的办法。
注意事项
- 如果脚本未指定 shebang ,脚本执行的时候,默认用当前 shell 去解释脚本,即 $SHELL
- 如果 sh ebang 指定了可执行解释器,比如 /bin/bash /user/bin/python ,脚本在执行时,文件名会作为参数传递给解释器
- 如果 #!指定的解释查询没有执行权限,则会报错
- 如果 #!指定的解释程序不是一个可执行文件,那么指定的解释程序会被被忽略,转交个当前的 SHELL 去执行这个脚本
- 如果你使用 bash text.sh 这样的命令去执行脚本,那么 #!这一行就会被忽略掉,解释器当然是用命令行中显示指定的 bash
脚本注释
可以让别人快速的读懂你写的脚本,还有利于自己后期去更改基本。使用英文注释,也可以用中文但是有可能会报错。
shell执行方法
- bash script.sh 或 sh scripte.sh,文件本身没有执行权限,则使用的方法,或者脚本未指定 sheban
- 使用 绝对/相对 路径来来执行脚本
- source script.sh 或者 ./script.sh,代表执行含义,source 等于 .
- sh < script.sh 很少人用的一种方法
shell父与子
1.source和点执行shell脚本,只在当前的shell环境中执行
2.指定bash sh解释器运行脚本,是开启了一个subshell,开启字shell运行脚本命令
3../script,都会指定shebang,通过解释器运行,也是开启subshell运行命令
ps -ef --forest
创建进程列表(创建子shell)
shell的进程列表理念,需要使用 () 小括号,括号里可以嵌套多个括号执行。可以使用shell这 () 命令进行多进程的处理,提高程序并发执行。
#$BASH_SUBSHELL 若在父shell中则返回零,反之其他数字
[root@shell ~]# (pwd;(cd /opt;(echo $BASH_SUBSHELL)))
/root
3
shell和运维
shell主要是来处理系统文本类型数据的,比如日志配置文件。shell 属于弱类型的脚本语言,无需声名变量类型,直接定义使用。
变量
pstree 检查进程树
变量定义与赋值,注意变量与值之间不得有空格
[root@shell ~]# name="花花"
[root@shell ~]# echo $name
花花
bash变量为弱类型,无需事先声明类型,是将声明和复制同时进行的
变量替换/引用
[root@shell ~]# music="花花"
[root@shell ~]# echo ${music}
花花
[root@shell ~]# echo $music
花花
[root@shell ~]# echo name
name
变量名规则
- 名称定义要做到简明知意,切按照规则来,切别的应用保留关键字
- 只能包含数字、字母、下划线
- 不能以数字开头
- 不能用标点符号
- 变量名严格区分大小写
#有效字符
[root@shell ~]# age=15
[root@shell ~]# name = "花花"
[root@shell ~]# _da=daf
[root@shell ~]# echo $_da
daf
#无效字符
[root@shell ~]# 2age=15
-bash: 2age=15: 未找到命令
[root@shell ~]# .age=55
-bash: .age=55: 未找到命令
变量作用域
父子关系:也就是说在父亲里的变量只能搜索到父亲的变量,搜索不到儿子的。相反儿子的也是。
[root@shell ttt]# cat make_var.sh
age='18'
[root@shell ttt]# age='20'
[root@shell ttt]# echo $age
20
[root@shell ttt]# bash make_var.sh
[root@shell ttt]# echo $age
20
[root@shell ttt]# source make_var.sh
[root@shell ttt]# echo $age
18
环境变量
环境变量也成为全局变量,针对当前 shell 以及其进程任意子进程,环境变量也分自定义变量、内置变量两种
局部变量
针对在 shell 中的函数或是 shell 脚本中定义
位置参数变量
用于 shell 脚本中传递的参数
特殊变量
shell 内置的特殊功效变量
- $?
- 0: 成功
- 1-255:报错
自定义变量
- 变量赋值:varName=value
- 变量引用:${varName}、$varName
单引号双引号
单引号变量,不识别特殊语法
双引号变量,能识别特殊符号
[root@shell ~]# name="小明"
[root@shell ~]# echo ${name}
小明
[root@shell ~]# name2='${name}'
[root@shell ~]#echo $name2
${name}
修改变量设置
环境变量,能找出你的 linux 服务器上的各种变量
- 每个用户都有自己的环境变量配置文件,~/.bash_profile ~/.bashrc,且以个人配置文件,优先加在变量,读取,以个人的优先生效
- 当你需要给所有用户都使用某个变量,写入全局即可 /etc/profile
检查系统环境变量命令
- set:输出所有变量,包括全局变量、局部变量
- env:只显示全局变量
- declare:输出所有的变量,如同set
- export:显示和设置环境变量值
[root@shell ~]# set
BASH=/usr/bin/bash
....
[root@shell ~]# set |wc -l //显示的行数
55
[root@shell ~]# env
XDG_SESSION_ID=13
....
[root@shell ~]# env | wc -l
21
撤销变量名
unset 取消变量名,删除变量或函数
设置只读变量
readonly,只有 shell 结束,只读变量实效
[root@shell ~]# readonly password="123"
[root@shell ~]# echo $password
123
[root@shell ~]# password="123456"
bash: password: 只读变量
系统保留环境变量关键字
bash 内嵌了诸多环境变量,用于定义 bash 的工作环境
# 去除空格冒号等于号 第三列的值
[root@shell ~]# export |awk -F '[ :=]' '{print $3}'
HISTCONTROL
......
bash
bash内置命令
echo; eval 执行多个命令; exec; export; read; shift
echo
-n 不换航输出
-e 解析字符内的特殊字符
/n 换行
/r 回车
/t 制表符
/b 退格
bash 多命令执行
用;来当分隔符
[root@shell etc]# ls /opt/ ; ls /proc/ ; cd /etc/
特殊变量
位置参数
$0 获取文件名
$n 获取第n个数据。例如:$1,$2,$3...大于9则 ${10}
$# 获取总个数
$* / $@ 获取脚本所有数据(它俩的区别在于输出方式不同,不加引号是没有区别的。"$*"是横列输出,"$@"是数列输出)
例子:
[root@shell opt]# cat text.sh
#!/bin/bash
echo "print \"\$*\""
for a in "$*"
do
echo "$a"
done
echo "print \"\$@\""
for a in "$@"
do
echo "$a"
done
[root@shell opt]# bash text.sh gm 1180 52 33
print "$*"
gm 1180 52 33
print "$@"
gm
1180
52
33
特殊状态变量
$? 上一次命令执行返回值,0成功,非0失败
$$ 当前shell脚本的进程号
$! 上一次后台进程的PID
$_ 上一次命令的最后一个参数
特殊shell扩展变量
这四个扩展变量都是属于对变量的值进行判断、处理
#word是一个值。也可以只写一个变量
变量1=${变量2:-word} 如果变量2为空则,则赋予变量1的值为word。反之变量1的值与变量2的值一样。
变量1=${变量2:=word} 如果变量2位空,则赋予变量1和变量2位word。反之变量1与变量2相等。
${变量:?word} 如果变量为空,则返回错误信息位word。反之返回变量值。
变量1=${变量2:+word} 如果变量为空,什么都不做。反之返回word
shell子串
shell变量的使用方法
${变量} 返回变量值 例:($name)
${#变量} 返回变量长度,字符串 例:($#name)
${变量:start} 返回变量offset数值之后的字符串 例:($name:2)
${变量:start:length} 提取offset之后的length限制的字符 例:($name:3:1)
删除
${变量#word} 从变量开头删除最短匹配的word字符串
${变量##word} 从变量开头删除最长匹配的word字符串
${变量%word} 从变量结尾删除最短的word
${变量%%word} 从变量结尾开始删除最长匹配的word
替换
${变量/pattern/string} 用string替代第一个匹配的pattern
${变量//pattern/string} 用string替代所有的pattern
sell编程,尽量使用linux内置命令,内置的操作和内置的函数,效率最高,尽可能的减少管道符的操作。
利用shell替换命令来修改文件名
[root@shell opt]# touch gm_{1..5}.jpg
[root@shell opt]# ls gm_*
gm_1.jpg gm_2.jpg gm_3.jpg gm_4.jpg gm_5.jpg
[root@shell opt]# for gm_name in `ls gm*.jpg` ; do mv $gm_name `echo ${gm_name//gm_/}`;done
[root@shell opt]# ls
1.jpg 2.jpg 3.jpg 4.jpg 5.jpg
数值计算(运算符)
关系运算符
字符串运算符
逻辑运算符
文件测试运算符
expr、bc命令
expr 运算命令
expr接受以空格分割的,多个参数
[root@shell ~]# expr 5 \+ 3 #加减运算需要加转义符 (\);+ - * / 都可以
8
[root@shell ~]# expr length 15894*() #字符长度
8
[root@shell ~]# expr gm.jpg ":" ".*j" #expr 字符串 ":" ".*+想要搜索的名字";返回的是第四个字符
4
测试
[root@shell opt]# cat text.sh
#!/bin/bash
for star in I am Guo Ming , I dont have a teacher.
do
#大于5的字符串
if [ `expr length $star` -lt 5 ]
then
echo $star
fi
done
[root@shell opt]# bash text.sh
I
am
Guo
Ming
,
I
dont
have
a
bc运算命令
bc是交互式计算,跟计算机一个道理。
[root@shell opt]# bc #计算机式计算
bc 1.06.95
...略
[root@shell opt]# echo "4*8" | bc #管道符式计算
32
中小括号计算
#中括号
[root@shell opt]# num=5
[root@shell opt]# res=$[num+6]
[root@shell opt]# echo $res
11
#小括号
[root@shell opt]# echo $num
5
[root@shell opt]# echo $((num*3))
15