Shell 基础
一、Shell
命令解释器,Shell是一个应用程序。它连接用户和Linux内核,让用户可以更加高效的使用Linux内核。
熟练地使用Shell可以使我们能够自动化地管理服务器集群
1.编程语言分类
- 编译型语言
程序使用前需要进行编译,编译器将程序编译为机器语言。程序执行效率高,但是跨平台性差。
- 解释型语言
程序不需要编译,程序运行时有解释器
翻译成机器语言,每次执行都需要翻译,相对来说效率较低,但是跨平台性好。
2.Shell脚本
Shell是一种脚本语言
简单来说就是将需要执行的命令全部保存到文本中,按照顺序从上往下一行行执行。
Shell 并不是简单的堆砌命令,我们还可以在 Shell 中编程
我们可以将一些重复性的工作写成Shell脚本,这样每次执行脚本就可以,大大提高我们的工作效率
Shell还可以:自动化部署软件环境、自动化分析处理、自动化 备份、自动化监控
①编写Shelll脚本:
#!/bin/bash
#Name:名字
#Desc:描述
#Path:存放路径
#Usage:用法
#Update:更新时间
注意:为了提高脚本兼容性可以使用 #! /usr/bin/env bash
来定义解释器
②执行脚本
# 方式1 ,需要为文件添加可执行权限
./脚本文件
# 方式2
bash 脚本文件
sh 脚本文件
查看执行过程
bash -x 脚本文件
语法检查
bash -n 脚本文件
二、变量
变量用来保存临时数据,变量值是可变的
当某个内容需要多次使用,我们就可以把它定义为一个变量,使用时直接使用变量
1. 变量定义要求
①变量名区分大小写
②变量名不能有特殊符号
③变量名不能以数字开头
④声明变量时两边不能有任何空格
⑤变量名需要做到见名知意
2. 变量定义及使用
①定义及取消变量
#1.定义变量
变量名=变量值
#2.删除变量
unset 变量名
②为变量赋值
# 1.普通赋值
变量名=值
# 2.将命令结果赋值给变量
变量名=$(命令)
变量名=`命令`
③使用变量
#1.方式1
$变量名
#2.方式2
${变量名}
#3.截取变量内容,0表示索引,3表示截取长度
${变量名:0:3}
4.交互式变量read
用户自己设定变量值
用法:# read [选项] 变量名
选项 | 描述 |
---|---|
-p | 设置提示消息 |
-s | 不显示输入内容 |
-t | 限制输入时间,默认单位为秒 |
-n | 定义字符长度,限制变量值长度 |
案例:
# 1.输入用户名
read -p "Please input your name:" name
# 2.输入密码
read -s -p "Please input your password:" password
# 3.定义多个变量,赋值时使用空格隔开
[root@source codes]# read -p "Please input your name and age:" name age
Please input your name and age:Tiger 22
# 4.从文件中读取变量值
read name age < test.txt
# test.txt 文件内容为“Tiger 22”,注意每个变量用空格隔开
5.declare
设置变量属性,可以设置变量类型,定义数组,将变量设置为环境变量等
常用选项:
选项 | 描述 |
---|---|
-i | 将变量定义为整数类型 |
-r | 将变量定义为只读 |
-a | 声明变量定义为普通数组 |
-A | 声明变量定义为关联数组 |
-x | 将变量设置为环境变量 |
6.变量分类
使用env
命令可以查看当前用户的环境变量
使用set
命令可以查看当前用户的所有变量(临时变量与环境变量)
环境变量相关文件:
文件 | 描述 |
---|---|
/etc/bashrc | 全局bash信息,定义alias 、umask 、函数 ,用户登录时读取 |
/etc/profile | 全局环境变量信息 |
~/.bash_profile | 当前用户的环境变量 |
~/.bashrc | 当前用户的bash信息 |
~/.bash_logout | 当用户退出shell时读取 |
~/.bash_history | 用户的历史命令 |
注意:文件修改后通过source
生效或者重新登录
配置文件执行顺序:
① /etc/profile
② ~/.bash_profile
③ ~/.bashrc
④ /etc/bashrc
7.系统变量
变量 | 描述 |
---|---|
$? | 上一条命令执行后返回的状态,0 表示正常 |
$0 | 当前执行的程序或脚本名 |
$# | 脚本后参数个数 |
$* | 脚本后所有参数, |
$@ | 脚本后所有参数,参数是独立的 |
$1-$9 | 脚本后的参数,$2 表示第二个位置的参数 |
${10}~${n} | 扩展位置参数,$10 表示第十个位置的参数2位数字以上的参数位置需要使用 {} |
$$ | 当前所在进程的进程号 |
$! | 后台运行的最后一个进程号 |
!$ | 调用最后一条命令历史中的参数 |
实例:
[root@source ~]# cat test.sh
#!/bin/bash
echo "\$0 = $0"
echo "\$# = $#"
echo "\$* = $*"
echo "\$@ = $@"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
echo "\$11 = ${11}"
[root@source ~]# ./test.sh a b c d e
$0 = ./test.sh
$# = 5
$* = a b c d e
$@ = a b c d e
$1 = a
$2 = b
$3 = c
$11 =
8.扩展
截取变量内容
str=/tmp/dir1/1.txt
#1.截取目录,结果为: /tmp/dir1
dirname $str
#2.截取文件名,结果为: 1.txt
basename $str
三、数组
Array,多个数据的集合,一个数据称为元素
可以简单的理解为将多个变量存放到一个变量中,然后通过
索引
进行赋值和获取Shell 并且没有限制数组的大小,理论上可以存放无限量的数据
Shell 是弱类型的,也就是说所有数组元素的类型不需要完全相同
1.普通数组
只能使用整数作为属组索引
①数组定义
# 1.一次赋一个值
arr1[0]=a
arr1[1]=b
arr1[2]=c
# 2.一次赋予多个值
arr2=(a b c)
arr3=(a b 123 "test")
②获取元素信息
#1.获取数组所有元素值
[root@source ~]# echo ${arr1[*]}
a b c
#2.获取数组第一个位置元素值,也就索引为0的位置的值
[root@source ~]# echo ${arr1[0]}
a
#3.获取数组第三个位置元素值,也就索引为2的位置的值
[root@source ~]# echo ${arr1[2]}
c
#4.获取数组第二个位置到第四个元素的值
[root@source ~]# echo ${arr1[@]:1:2}
b c
#5.获取数组所有索引信息
[root@source test2]# echo ${!arr1[@]}
0 1 2
#6.获取数组长度
[root@source test2]# echo ${#arr1[@]}
4
2.关联数组
可以使用字符串作为属组索引
①定义
# 1.一次赋一个值
declare -A arr1
arr1[a]=aaa
arr1[b]=bbb
arr1[c]=ccc
# 2.一次赋予多个值
declare -A arr2
arr2=([a]=aaa [b]=bbb [c]=ccc)
②获取元素信息
#1.查看所有关联数组信息
declare -A
#2.获取关联数组所有值
echo ${arr3[*]}
#3.获取单个值
echo ${arr3[b]}
#4.获取关联数组所有索引信息
echo ${!arr3[*]}
#5.获取关联属组长度
echo ${#arr3[*]}
四、四则运算
计算方式:
$(( ))
$[ ]
expr
let
五、函数
1.语法结构
函数名()
{
函数体
}
#--------------------
function 函数名()
{
函数体
}
return
1.结束函数
2.定义函数返回值
3 如果不加,将以最后一条命令运行结果或状态值,作为返回值
参数
通过$n
获取参数值
函数调用
直接使用函数名进行调用,后可接参数
2.案例
记录用户信息并在最后输出
#!/bin/bash
record()
{
read -p "$1" var
[ -z $var ] && record "$1" || echo $var
}
name=`record "Please input your Name:"`
gender=`record "Please input your Gender:"`
age=`record "Please input your Age:"`
echo "Your name is $name. Your gender is $gender. Your age is $age"
定义菜单函数
#!/bin/bash
menu()
{
cat <<-EOF
1. Service1
2. Service2
h. help
q. exit
EOF
}
menu