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信息,定义aliasumask函数,用户登录时读取
/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
Last modification:November 5th, 2019 at 11:00 pm