1.shell简介
shell就是人机交互的一个桥梁
shell的种类:
[root@myhost ~]# cat /etc/shells
- /bin/sh #是bash的一个快捷方式
- /bin/bash #bash是大多数Linux默认的shell,包含的功能几乎可以涵盖shell所有的功能
- /sbin/nologin #表示非交互,不能登录操作系统
- /bin/dash #小巧,高效,功能相比少一些
- /bin/csh #具有C语言风格的一种shell,具有许多特性,但也有一些缺陷
- /bin/tcsh #是csh的增强版,完全兼容csh
2.shell脚本
就是将需要执行的命令保存到文本中,按照顺序执行。它是解释型的,意味着不需要编译。
shell脚本的基本写法
1)脚本第一行,#!指定解释器
!/bin/bash #表示使用bash解释器解析
注意: 如果直接将解释器路径写死在脚本里,可能在某些系统就会存在找不到解释器的兼容性问题,所以可以使用: #!/bin/env 解释器
2)脚本第二部分,注释(#号)说明,对脚本的基本信息进行描述【可选】
3)脚本第三部分,脚本要实现的具体代码内容
如:
#!/bin/env bash
# 以下内容是对脚本的基本信息的描述
# Name: 名字
# Desc:描述describe
# Path:存放路径
# Usage:用法
# Update:更新时间
#下面就是脚本的具体内容
commands
...
shell脚本的执行方法
标准脚本执行方法(建议)
1) 编写第一个shell脚本
[root@myhost shell01]# cat first_shell.sh
#!/bin/env bash
# 以下内容是对脚本的基本信息的描述
# Name: first_shell.sh
# Desc: num1# Path: /shell01/first_shell.sh
# Usage:/shell01/first_shell.sh
# Update:2019-05-05
echo "hello world"
echo "hello world"
echo "hello world"
2) 脚本增加可执行权限
[root@myhost shell01]# chmod +x first_shell.sh
3) 标准方式执行脚本
[root@myhost shell01]# pwd
/shell01
[root@myhost shell01]# /shell01/first_shell.sh
或者
[root@myhost shell01]# ./first_shell.sh
注意:标准执行方式脚本必须要有可执行权限。
非标准的执行方法(不建议)
- 直接在命令行指定解释器执行
[root@myhost shell01]# bash first_shell.sh
[root@myhost shell01]# sh first_shell.sh - 使用 source 命令读取脚本文件,执行文件里的代码
[root@myhost shell01]# source first_shell.sh
hello world
hello world
hello world
注:bash中的引号
双引号"" :会把引号的内容当成整体来看待,允许通过$符号引用其他变量值
单引号’’ :会把引号的内容当成整体来看待,禁止引用其他变量值,shell中特殊符号都被视为普通字符
反撇号`` :反撇号和$()一样,引号或括号里的命令会优先执行,如果存在嵌套,反撇号不能用
[root@myhost dir1]# echo "$(hostname)"
myhost #双引号按照实际指令打印
[root@myhost dir1]# echo '$(hostname)'
$(hostname) #单引号将其中内容视作字符串打印
注:
echo -e "hello\nworld\c" # -e 开启转义 \n:换行 \c:不换
3.注释
会被解释器忽略
单行注释格式:
# 这是一个注释
多行注释格式:
<<EOF
注释内容...
注释内容...
注释内容...
EOF
说明:EOF 也可以使用其他符号
4.变量
变量是用来临时保存数据的,该数据是可以变化的数据。
1)变量定义
变量名=变量值
变量名:用来临时保存数据的
变量值:就是临时的可变化的数据
[root@myhost ~]# A=hello 定义变量A
[root@myhost ~]# echo $A 调用变量A
hello
[root@myhost ~]# echo ${A} 还可以这样调用
hello
[root@myhost ~]# A=world 因为是变量所以可以变
[root@myhost ~]# echo $A
world
[root@myhost ~]# unset A 删除变量
[root@myhost ~]# echo $A
2)变量的定义规则
㈠ 变量名区分大小写
[root@myhost ~]# A=hello
[root@myhost ~]# a=world
[root@myhost ~]# echo $A
hello
[root@myhost ~]# echo $a
world
㈡ 变量名不能有特殊符号
[root@myhost ~]# *A=hello
-bash: *A=hello: command not found
[root@myhost ~]# ?A=hello
-bash: ?A=hello: command not found
特别说明:对于有空格的字符串给变量赋值时,要用引号引起来
[root@myhost ~]# A=hello world
-bash: world: command not found
[root@myhost ~]# A=“hello world”
[root@myhost ~]# A=‘hello world’
㈢ 变量名不能以数字开头
[root@myhost ~]# 1A=hello
-bash: 1A=hello: command not found
[root@myhost ~]# A1=hello
注意:不能以数字开头并不代表变量名中不能包含数字。
㈣ 等号两边不能有任何空格
㈤ 变量名尽量做到见名知意
3)变量的定义方式
㈠ 基本方式
直接赋值给一个变量
[root@myhost ~]# A=1234567
[root@myhost ~]# echo $A
1234567
[root@myhost ~]# echo ${A:2:4} 表示从A变量中第3个字符开始截取,截取4个字符
3456
说明:
$变量名 和 ${变量名}的异同
相同点:都可以调用变量
不同点:${变量名}可以只截取变量的一部分,而$变量名不可以
㈡ 命令执行结果赋值给变量
[root@myhost ~]# B=‘date +%Y’
[root@myhost ~]# echo $B
2022
[root@myhost ~]# C=$(hostname)
[root@myhost ~]# echo $C
myhost
㈢ 交互式定义变量(read)
目的:让用户自己给变量赋值,比较灵活。
语法: read [选项] 变量名
常见选项:
read -p(提示信息) -n(限制变量值长度) -s(隐藏输入内容) -t(定义超时时间)
举例
用法1:用户自己定义变量值
[root@myhost ~]# read -p “输入你的姓名:” name
输入你的姓名:tom
用法2:变量值来自文件
[root@myhost ~]# cat 1.txt
abc
[root@myhost ~]# read c < 1.txt (<箭头朝谁就向谁写入)
[root@myhost ~]# echo $c
abc
㈣ 定义有类型的变量(declare)
目的:给变量做一些限制,固定变量的类型,比如:整型、只读
用法: declare 选项 变量名=变量值
常用选项:
declare -i(看成整数) -r(定义只读)
举例说明:
[root@myhost ~]# declare -i A=123
[root@myhost ~]# echo $A
123
[root@myhost ~]# A=hello
[root@myhost ~]# echo $A
0
[root@myhost ~]# declare -r B=hello
[root@myhost ~]# echo $B
hello
[root@myhost ~]# B=world
-bash: B: readonly variable
[root@myhost ~]# unset B
-bash: unset: B: cannot unset: readonly variable
4.变量的分类
㈠ 本地变量
本地变量:当前用户自定义的变量。当前进程中有效,其他进程及当前进程的子进程无效。
㈡ 环境变量
环境变量:当前进程有效,并且能够被子进程调用。
env 查看当前用户的环境变量
set 查询当前用户的所有变量(临时变量与环境变量)
export 变量名=变量值
或者
变量名=变量值;
export 变量名
[root@myhost ~]# export A=hello 临时将一个本地变量(临时变量)变成环境变量
[root@myhost ~]# env|grep A
A=hello
永久生效: vi /etc/profile 或者 ~/.bash_profile
export A=hello
㈢ 全局变量
全局变量:全局所有的用户和程序都能调用,且继承,新建的用户也默认能调用.
解读相关配置文件
说明:以上文件修改后,都需要重新source(源)让其生效或者退出重新登录。
用户登录系统读取相关文件的顺序
- /etc/profile
- $HOME/.bash_profile
- $HOME/.bashrc
- /etc/bashrc
- $HOME/.bash_logout
㈣ 系统变量
系统变量(内置bash中变量) : shell本身已经固定好了它的名字和作用.
{} 可使数据以一个单位输出
exit : 退出
#!/bin/bash
for i in "$@"
do
echo $i
done
echo "======我是分割线======="
for i in "$*"
do
echo $i
done
[root@myhost ~]# bash 3.sh a b c
a
b
c
======我是分割线=======
a b c
5.简单四则运算
算术运算:默认情况下,shell就只能支持简单的整数运算
运算内容:加(+)、减(-)、乘(*)、除(/)、求余数(%)
保持取整原则
1)四则运算符号
不加let会导致输出字符串
2)i++和++i
对变量的值的影响
[root@myhost ~]# i=1
[root@myhost ~]# let i++
[root@myhost ~]# echo $i
2
[root@myhost ~]# j=1
[root@myhost ~]# let ++j
[root@myhost ~]# echo $j
2
对表达式的值的影响
[root@myhost ~]# unset i j #unset删除变量
[root@myhost ~]# i=1;j=1
[root@myhost ~]# let x=i++ 滞后性
[root@myhost ~]# let y=++j 立即执行+1
[root@myhost ~]# echo $i
2
[root@myhost ~]# echo $j
2
[root@myhost ~]# echo $x
1
[root@myhost ~]# echo $y
2
6.数组
㈠ 数组分类
普通数组:只能使用整数作为数组索引(元素的下标) 相当于py的列表
关联数组:可以使用字符串作为数组索引(元素的下标)相当于py的字典
直接echo 数组名 只显示第一个元素
echo ${a[*]} 元素展现
echi ${!a[*]} 下标展现@也可代替*
㈡ 普通数组定义
一次赋予一个值
数组名[索引下标]=值
array[0]=v1
array[1]=v2
array[3]=v3
一次赋予多个值
数组名=(值1 值2 值3 …) 注:用空格隔开每个元素
array=(var1 var2 var3 var4)
array1=($(cat /etc/passwd))
array2=(`ls /home/tom`)
array3=(harry amy jack “jerry”)
array4=(1 2 3 4 “hello world” [10]=linux)
注:array4会在打印下标10以后越过前方没有打印的下标位置
㈢ 数组的读取
${数组名[元素下标]}
echo ${array[0]} 获取数组里第一个元素
echo ${array[*]} 获取数组里的所有元素
echo ${#array[*]} 获取数组里所有元素个数
echo ${!array[*]} 获取数组元素的下标
echo ${array[*]:1:2} 访问指定的元素;1代表从下标为1的元素开始获取;2代表截取长度
查看普通数组信息:
[root@myhost ~]# declare -a
循环数组
for item in ${arr[*]} ; do
echo $item
echo下标${item} 的值为${new{[i]}}
done
㈣ 关联数组定义
①首先声明关联数组
declare -A asso_array1
declare -A asso_array2
declare -A asso_array3
注:关联数组需要声明,否则后面的元素会覆盖前面的
② 数组赋值
一次赋一个值
数组名[索引or下标]=变量值
# asso_array1[linux]=one
# asso_array1[java]=two
# asso_array1[php]=three
一次赋多个值
# asso_array2=([name1]=harry [name2]=jack [name3]=amy [name4]="jack")
查看关联数组
# declare -A
declare -A asso_array1='([php]="three" [java]="two" [linux]="one" )'
declare -A asso_array2='([name3]="amy" [name2]="jack" [name1]="harry" [name4]="jack" )'
获取关联数组值
echo ${asso_array1[linux]}
one
echo ${asso_array1[php]}
three
echo ${asso_array1[*]}
three two one
echo ${!asso_array1[*]}
php java linux
echo ${#asso_array1[*]}
3
echo ${#asso_array2[*]}
4
echo ${!asso_array2[*]}
name3 name2 name1 name4
7.其他变量定义
取出一个目录下的目录和文件: dirname 和 basename
# A=/root/Desktop/shell/mem.txt
# echo $A
/root/Desktop/shell/mem.txt
# dirname $A 取出目录
/root/Desktop/shell
# basename $A 取出文件
mem.txt
变量"内容"的删除和替换
删除:%,#
一个“%”代表从右往左去掉一个/key/
两个“%%”代表从右往左最大去掉/key/
一个“#”代表从左往右去掉一个/key/
两个“##”代表从左往右最大去掉/key/
举例说明:
# url=www.taobao.com
# echo ${#url} 获取变量的长度
# echo ${url#*.} taobao.com 每个点为一个key
# echo ${url##*.}com
# echo ${url%.*} www.taobao
# echo ${url%%.*} www
替换:/ 和 //
echo ${url/ao/AO} /只替换第一个
echo ${url//ao/AO} //替换全部
替代: -和 :- +和:+
${变量名-新的变量值} 或者 ${变量名=新的变量值}
变量没有被赋值:会使用“新的变量值“ 替代
变量有被赋值(包括空值): 不会被替代
有值就取值,没有就取默认值
echo ${abc-123}
123
abc=hello
hello
echo ${abc-444}
hello
${变量名:-新的变量值} 或者 ${变量名:=新的变量值}
变量没有被赋值或者赋空值:会使用“新的变量值“ 替代
变量有被赋值: 不会被替代
echo ${ABC:-123}
ABC=HELLO
echo ${ABC:-123}
ABC=
echo ${ABC:-123}
${变量名+新的变量值}
变量没有被赋值:不会使用“新的变量值“ 替代
变量有被赋值或者赋空值: 会被替代
[root@myhost ~]# echo ${abc+123}
[root@myhost ~]# abc=hello
[root@myhost ~]# echo ${abc+123}
123
[root@myhost ~]# abc=
[root@myhost ~]# echo ${abc+123}
123
${变量名:+新的变量值}
变量没有被赋值(包括空值):不会使用“新的变量值“ 替代
变量有被赋值: 会被替代
[root@myhost ~]# echo ${abc:+123}
[root@myhost ~]# abc=hello
[root@myhost ~]# echo ${abc:+123}
123
[root@myhost ~]# abc=
[root@myhost ~]# echo ${abc:+123}
${变量名?新的变量值}
变量没有被赋值:提示信息
变量被赋值(包括空值):不会使用“新的变量值“ 替代
[root@myhost ~]# echo ${abc?123}
-bash: abc: 123
[root@myhost ~]# abc=hello
[root@myhost ~]# echo ${abc?123}
hello
[root@myhost ~]# abc=
[root@myhost ~]# echo ${abc?123}