一、脚本实践
脚本示例1
-- 直接编辑并创建一个文件
vim bak.sh
-- 写入下面这句话
# 获取ip地址信息
ifconfig ens33 | grep -w inet | awk '{print $2}' | xargs echo "IP: "
-- 运行bak文件
bash bak.sh
或者
-- 添加可执行权限
chmod a+x bak.sh
./bak.sh
或者
source bak.sh
检查脚步是否有错误
调试方式
-n 检查脚本中的语法错误
-v 先显示脚本所有内容,然后执行脚本,结果输出,如果执行遇到错误,将错误输出。
-x 将执行的每一条命令和执行结果都打印出来
语法
bash 【选项】 【文件名】
二、shell变量
2.1 变量分类
shell 中的变量分为三大类:
本地变量 变量名仅仅在当前终端有效
全局变量 变量名在当前操作系统的所有终端都有效
shell内置变量 shell解析器内部的一些功能参数变量
注意:
这里的变量分类的特点仅仅是从字面上来理解的,因为在实际的操作的时候,还会涉及到环境优先级的问题
所以生产中对于这三者的划分没有特别大的强制。
局部变量示例:
-- 定义局部变量
name=lsh
echo $name
注意:定义变量不要空格
-- 错误示例
name1 = lsh
现在定义的局部变量只对当前的终端生效,当你关闭虚拟机的时候,再重新登录,就没有这个变量
全局变量示例:
vim /etc/profile
name2=jack
临时全局变量定义:
export qwe=jack
echo qwe
他们两个区别:
在于export定义的变量在系统重启后会消失
类型变量示例:
命令语法
declare 参数 变量名=变量值
参数解析:
-i 将变量看成整数
-r 使变量只读 readonly,该变量的值无法改变,并且不能为unset
-x 标记变量为全局变量,类似于export
-a 指定为索引数组(普通数组);查看普通数组
-A 指定为关联数组;查看关联数组
注意:
在生产场景中,这种方法比较鸡肋,使用频率 0-20次/3年
设定制定类型的变量值
[root@localhost ~]# declare -i mynum='shuzi'
[root@localhost ~]# echo $mynum
0
[root@localhost ~]# declare -i mynum='123456'
[root@localhost ~]# echo $mynum
123456
设定只读类型变量
[root@localhost ~]# declare -r myread1="aaa"
[root@localhost ~]# myread2=myread
[root@localhost ~]# readonly myread2
查看只读变量
[root@localhost ~]# declare -r | grep myread
declare -r myread1="aaa"
declare -r myread2="myread"
[root@localhost ~]# readonly -p | grep myread
declare -r myread1="aaa"
declare -r myread2="myread"
无法使用unset删除只读变量
[root@localhost ~]# unset myread1 myread2
bash: unset: myread1: 无法反设定: 只读 variable
bash: unset: myread2: 无法反设定: 只读 variable
借助于exit方式删除只读变量
[root@localhost ~]# exit
...... 重新登录后再次查看
[root@localhost ~]# declare -r | grep myread
[root@localhost ~]#
命令变量:
定义方式一:
变量名=`命令`
注意:
` 是反引号
定义方式二:
变量名=$(命令)
示例:
方法1设定变量名
[root@localhost ~]# myuser=`whoami`
[root@localhost ~]# echo $myuser
root
变量移除:
语法解析:
基本格式
unset 变量名
查看刚才定制的变量名
[root@localhost ~]# echo $myname
shuji
移除变量名
[root@localhost ~]# unset myname
[root@localhost ~]# echo $myname
[root@localhost ~]#
嵌套shell:
-- 编辑父脚本
vim father.sh
-- 写入以下内容
#!/bin/bash
# 定制全局变量
export _xing='王'
_name="书记"
_age="42"
echo "父shell信息: $_xing$_name,$_age"
bash son.sh
sleep 3
-- 编辑子脚本
vim son.sh
-- 写入以下内容
#!/bin/bash
# 显示父shell的全局变量
echo "子shell信息: $_xing$_name,$_age"
bash father.sh
内置变量:
| 序号 | 变量名 | 解析 |
| ---- | ------ | ------------------------------------------------------------ |
| 1 | $0 | 获取当前执行的shell脚本文件名 |
| 2 | $n | 获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9就要用大括号括起来${10} |
| 3 | $# | 获取当前shell命令行中参数的总个数 |
| 4 | $? | 获取执行上一个指令的返回值(0为成功,非0为失败)
编辑一个sc.sh脚本
字符串相关:
字符串计数
${#file} 获取字符串的长度字符串截取
- 语法为${var:pos:length} 表示对变量var从pos开始截取length个字符,pos为空标示0
${file:0:5} 从0开始,截取5个字符
${file:5:5} 从5开始,截取5个字符
${file::5} 从0开始,截取5个字符
${file:0-6:3} 从倒数第6个字符开始,截取之后的3个字符
${file: -4} 返回字符串最后四个字节,-前面是"空格"
简单实践
定制字符串内容
[root@localhost ~]# string_context="dsjfdsafjkldjsklfajkdsa"
[root@localhost ~]# echo $string_context
dsjfdsafjkldjsklfajkdsa
获取字符串长度
[root@localhost ~]# echo ${#string_context}
23
从0开始,截取5个字符
[root@localhost ~]# echo ${string_context:0:5}
dsjfd
从5开始,截取5个字符
[root@localhost ~]# echo ${string_context:5:5}
safjk
从0开始,截取5个字符
[root@localhost ~]# echo ${string_context::5}
dsjfd
从倒数第6个字符开始,截取之后的3个字符
[root@localhost ~]# echo ${string_context:0-6:3}
ajk
返回字符串最后四个字节,-前面是"空格"
[root@localhost ~]# echo ${string_context: -4}
kdsa
默认值相关:
语法:
格式一:${变量名:-默认值}
变量a如果有内容,那么就输出a的变量值
变量a如果没有内容,那么就输出默认的内容
格式二:${变量名+默认值}
无论变量a是否有内容,都输出默认值
实践1 - 有条件的默认值
购买手机的时候选择套餐:
如果我输入的参数为空,那么输出内容是 "您选择的套餐是: 套餐 1"
如果我输入的参数为n,那么输出内容是 "您选择的套餐是: 套餐 n"
[root@localhost ~]# select_default_value.sh
#!/bin/bash
# 套餐选择演示
a="$1"
echo "您选择的手机套餐是: 套餐 ${a:-1}"
实践2 - 强制默认值
国家法律强制规定:
不管我说国家法定结婚年龄是多少岁,都输出 国家法定结婚年龄(男性)是 22 岁
[root@localhost ~]# froce_default_value.sh
#!/bin/bash
# 默认值演示示例二
a="$1"
echo "国家法定结婚年龄(男性)是 ${a+22} 岁"
其他相关:
基础知识:
序号 | 变量名 | 解析 |
---|---|---|
1 | $_ | 在此之前执行的命令或脚本的第一个内容 |
2 | $@ | 传给脚本的所有参数 |
3 | $* | 是以一个单字符串显示里所有向脚本传递的参数,与位置参数不同,参数可超过9个 |
4 | $$ | 是脚本运行的当前进程的ID号,作用是方便以后管理它杀掉他 |
5 | $! | 前一条命令进程的ID号,作用是方便以后管理它杀掉他 |
[root@localhost ~]# vim get_other.sh
-- 写入以下内容
#!/bin/sh
echo "脚本执行命令的第一个内容: $_"
echo "传递给当前脚本的所有参数是: $@"
echo "单字符串显示所有参数: $*"
echo "当前脚本执行时候的进程号是: $$"
sleep 5 &
echo "上一条命令执行时候的进程号是: $!"
-- 然后运行
bash get_other.sh