shell入门及变量
shell基础入门
为什么使用shell
1.安装操作系统(centos)自动化安装操作系统底层shell
2.初始化/优化操作系统
1) ntp时间同步
2)更改默认yum源
3)ssh优化
4)关闭selinux
5)关闭/开启防火墙(c6:iptables c7: firewalld)
- 安装基础服务
7)优化文件描述符
8)优化字符集
shell中的变量
3.安装服务
4.启动服务
5.脚本实现自动化代码上线
6.监控服务
7.结合定时任务使用shell
8.重复性工作写入脚本
1)日志切割
2)日志分析
3)数据统计
4)机器巡检
5)数据备份
shell编程需要掌握的基础知识
1)熟练使用vim编辑器
2)熟悉ssh终端
3)熟练掌握linux的命令
4)熟练掌握linux正则表达式及三剑客命令
5)vscode
shell脚本规范
1.目录统一
2.shell脚本的结尾要以.sh结尾
3.脚本的开头需要解释器
#!/bin/bash
4.作者信息
#!/bin/bash
#Author: _wc_
#Date: _1999-12-21_
#Name: _Print Message_
- 一定要有注释
- shell尽量使用英文
- 成对的符号和语句一次性写完
vim摸板
# 1.首先先编辑一个摸板文件,该摸板文件可以叫任何名字
[root@m01 ~]# vim /root/.vimrc
autocmd bufNewFile *.py,*.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.1__ ")
call setline(5, "# Author: __DriverZeng__ ")
call setline(6, "# Mail: __2794552827@qq.com__ ")
call setline(7, "# Blog: __https://blog.driverzeng.com__ ")
call setline(8, "# DateTime: __".expand(strftime("%Y-%m-%d %H:%M")) . "__")
endif
endfunc
# 接下来,我们编辑所有只要以.sh结尾的文件.都会带作者信息
脚本执行方式
[root@m01 ~]# vim test.sh
#!/bin/bash
#Author: _DriverZeng_
#Date: _1999-12-21_
#Name: _Print Message_
echo 'Hello World'
# 执行脚本
[root@m01 ~]# sh test.sh
Hello World
[root@m01 ~]# bash test.sh
Hello World
[root@m01 ~]# ./test.sh
Hello World
[root@m01 ~]# /root/test.sh
Hello World
[root@m01 ~]# . test.sh
Hello World
[root@m01 ~]# source test.sh
Hello World
. 和 source 都是在父shell下执行的sh ,bash,相对路径,绝对路径都是在子shell下执行的
开发语言中程序代码分类
-
编译型
写完后,需要编译才能运行。开发书写的代码,无法直接运行,需要编译(Java、C语言、等)
-
解释型
书写完成,通过命令解释器运行。书写完成后,使用对应的命令解释器(shell、python、等)
变量介绍
变量即变化的量,核心是变与量的二字,变即变化,量即衡量的状态
量:是记录现实世界当中的某种状态
变:指的是记录的状态是可以发生变化的
# name = wc
age = 18
如何使用变量
变量名 赋值符号 变量值
name = wc // shell中定义的变量
name : wc // yaml中定义的变量
定义变量的语法
1)变量名
相当于一个门牌号,便于取出变量值,是访问到值的唯一方式
2)赋值符号
将值得内存地址,绑定给变量名
3)变量值
用来表示状态
变量的使用规则:先定义,在通过变量名去引用
定义变量名的规范
# 变量命名的规则
1.大前提:变量名的命名应该能够反映出值记录的状态。
2.变量是用来访问变量值的,所以变量名应该遵循一定规范,来方便我们标识存到内存中值的功能。
3.变量名只能是 字母、数字或下划线的任意组合(区分大小写)
4.变量名不可以使用中文
5.变量名,不要使用命令来命名
6.不要用拼音
7.变量名不能以数字开头
变量名定义的方式
1.下划线+纯小写
name_of_h1='jilei'
name_of_h2='wanglei'
2.驼峰体
Name_of_h1='jilei'
3.下划线+纯大写
NAME_OF_H1='jilei'
不好的方式:
1)变量名为中文、拼音
2)变量名过长
3)变量名词不达意
变量的分类
系统内置环境变量
# 查看系统环境变量
env
declare
export
# 环境变量
LANG # 字符集语言
PATH # 该变量中的路径里的所有可执行文件,都是可以直接执行,不需要加路径
PS1 # 命令提示符
UID # 当前登录用户的uid
HOSTNAME # 当前主机名
PWD # 当前工作路径
USER # 当前登录的用户名
# 历史记录相关
HISTSIZE # history 命令输出的记录数,默认1000行
HISTFILESIZE # .bash_history 中保存命令的记录总数
HISTFILE # 指定存放历史命令的文件,默认是~/.bash_history
TMOUT # 将值设置为readonly 防止用户更改
HISTCONTROL: export HISTCONTROL=ignorespace # 忽略空格
PROMPT_COMMAND # 记录用户历史命令
普通变量
DATE=$(date + %F-%T)
IP=(ifconfig eth1|awk 'NR==2{print $2}')
# 使用大括号分隔变量
mkdir ${DATE}_${IP}_${HOSTNAME}
位置变量
# $0
[root@m01 ~]# vim s.sh
#!/bin/bash
# File Name: __s.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-18 15:59__
echo $0
[root@m01 ~]# sh s.sh
s.sh
# $n
[root@m01 ~]# vim s.sh
#!/bin/bash
# File Name: __s.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-18 15:59__
echo $1 $2 $3
[root@m01 ~]# sh s.sh a b cc
a b cc
# $#
[root@m01 ~]# vim s.sh
#!/bin/bash
# File Name: __s.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-18 15:59__
echo $1 $2 $3
echo $#
[root@m01 ~]# sh s.sh a b cc
a b cc
3
# $* 与 $@ 区别
[root@m01 ~]# vim s.sh
#!/bin/bash
# File Name: __s.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-18 15:59__
echo '$*结果: '
for i in $*;do
echo $i
done
echo '$@结果: '
for i in $@;do
echo $i
done
[root@m01 ~]# sh s.sh a b cc
$*结果:
a
b
cc
$@结果:
a
b
cc
$*和$@ 加引号的区别
[root@m01 ~]# vim s.sh
#!/bin/bash
# File Name: __s.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-18 15:59__
echo '$*结果: '
for i in "$*";do
echo $i
done
echo '$@结果: '
for i in "$@";do
echo $i
done
[root@m01 ~]# sh s.sh a b cc
$*结果:
a b cc
$@结果:
a
b
cc
# 总结:
$N: N正整数,$1,$2...$N 两位数要使用{},${11} ${10}
$0: 执行脚本的路径和名字
$#: 统计脚本参数的个数
$*: 接受脚本后面的所有参数
$@: 接受脚本后面的所有参数
$* 和 $@的区别
$*
1.不适合数组使用
2.调用双引号(横着显示)
$@
1.适合数组使用
2.调用双引号(竖着显示)
符号 | 含义 | 应用 |
---|---|---|
$0 | 执行脚本的名字 | 脚本使用方法常用:给出错误提示或者使用帮助 |
$N | 脚本的第N的参数 | 命令传参,传递给脚本,在脚本中使用 |
$# | 统计脚本参数的个数 | 判断脚本是否传参 |
$* | 获取脚本所有的参数 | 将所有参数当成一个整体,对传递的参数进行判断 |
$@ | 获取脚本所有的参数 | 将每一个参数当成是一个整体,对传递的参数进行判断 |
特殊变量(状态)
# $? 表示上一个命令执行的状态(上一条命令的返回值)0 成功执行 非0失败
特殊命令:
- false
- diff
# $$ 表示当前脚本执行的pid
# $! 上一个脚本或者程序运行的pid
# $_ 获取上一条命令的最后一个参数(以空格为分隔符) 类似于ESC + .
举例
[root@m01 ~]# vim test.sh
#!/bin/bash
# File Name: __test.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-19 14:42__
ls /root/ > /dev/null &
echo $?
echo $$ > /tmp/pid.txt
echo $_
[root@m01 ~]# sh test.sh
0
echo
变量的子串
# ${#变量名} 获取该变量的值长度
# ${变量名} 调用变量
# ${变量名:偏移量} 字符串的截取
# ${变量名:偏移量:步长} 字符串的截取
[root@m01 ~]# vim test.sh
#!/bin/bash
# File Name: __test.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-19 14:42__
name=wangcheng
echo ${name:6:3}
[root@m01 ~]# sh test.sh
eng
# ${变量名#字符串} 从变量开头,删除最短匹配的字符串的子串
# ${变量名##字符串} 从变量开头,删除最长匹配的字符串的子串
[root@m01 ~]# vim test.sh
#!/bin/bash
# File Name: __test.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-19 14:42__
for line in `cat 1.txt`;do
echo ${line#*a}
echo ${line##*a}
done
[root@m01 ~]# vim 1.txt
adsadawdwa
[root@m01 ~]# sh test.sh
dawdwa
全部删除
# ${变量名/匹配内容/替换内容} 只替换第一个匹配到的内容
# ${变量名//匹配内容/替换内容} 替换所有匹配到的内容
[root@m01 ~]# vim test.sh
#!/bin/bash
# File Name: __test.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-19 14:42__
read -p '请输入用户名: ' name
echo ${name/sb/jilei}
echo ${name//sb/jl}
[root@m01 ~]# sh test.sh
请输入用户名: sb_wc_wcwsb
jilei_wc_wcsb
jl_wc_wcjl
扩展变量
# ${变量名:-字符串}:如果parameter没被赋值或其值为空,就以string作为默认值,它不会赋值给变量
# ${变量名:=字符串}:如果parameter没被赋值或其值为空,就以string作为默认值,它会赋值给变量(用户没有传递值)
# ${变量名:?报错信息}:如果parameter没被赋值或其值为空,就以?后面的字符串作为报错输出
# ${变量名:+字符串}:如果parameter没被赋值或其值为空,就什么都不做,否则用string替换变量内容
变量的复制方式
# 直接赋值: name=wls
# 间接赋值:IP=`ifconfig eth1|awk 'NR==2{print $2}'`
# 交互赋值: read -p '请输入' 变量名
# 传参赋值: $1 $2 $3 ...
交互式赋值
read 选项 变量名
-p: 打印一句话
-s:不显示输入的内容
-t:设置超时时间
-a:将后面所有结果放入数组
shell中的数据类型
# 字符串类型
赋值:
name=`字符串`
取值:
$name
# 整形
age=`18`
# 数组类型
[root@m01 ~]# vim test.sh
#!/bin/bash
# File Name: __test.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-19 14:42__
list=(cjk jl bdyjy sb)
echo $list
echo ${list[1]}
echo ${list[2]}
[root@m01 ~]# sh test.sh
cjk
jl
bdyjy
# 循环数组
[root@m01 ~]# vim test.sh
#!/bin/bash
# File Name: __test.sh__
# Version: __v1.1__
# Author: __WC__
# Mail: __2794552827@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2022-07-19 14:42__
list=(cjk jl bdyjy sb)
for xunhuan in ${#list[*]};do
echo $xunhuan
done