一 什么是SHELL?
-
编程语言:java、python、lua、Go、C语言、C++、C#... SHELL语言
-
python程序开发:人工智能、ChatGPT
-
shell:运维领域、云计算领域
-
/etc/shell文件:专门用于存储系统支持的解释器
[root@shell ~]# cat /etc/shells #查看系统有哪些解释器
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
二 创建用户指定解释器
[root@shell ~]# useradd -s /bin/sh lisi #创建用户lisi指定解释器为/bin/sh
[root@shell ~]# grep lisi /etc/passwd #从/etc/passwd文件中过滤lisi信息
lisi:x:1000:1000::/home/lisi:/bin/sh
[root@shell ~]# useradd zhangsan #创建zhangsan用户,未指定解释器默认为/bin/bash
[root@shell ~]# grep zhangsan /etc/passwd #从/etc/passwd文件中过滤zhangsan信息
zhangsan:x:1001:1001::/home/zhangsan:/bin/bash
三 修改用户解释器
-
usermod -s 解释器 用户
-
chsh -s 解释器 用户
[root@shell ~]# usermod -s /bin/bash lisi #修改lisi的解释器为/bin/bash
[root@shell ~]# chsh -s /bin/sh zhangsan #修改zhangsan的解释器为/bin/sh
Changing shell for zhangsan.
Shell changed.
四 Bash解释器特性
-
支持快捷键、TAB补全
-
别名(alias)
-
历史命令(history)
-
重定向(>、>>、2>、2>>、&>、&>>)
-
管道
五 重定向
-
创建文件
-
将内容重新定向输出
1>: 正确信息重定向(覆盖),直接写>等于1>
1>>: 正确信息重定向(追加),直接写>>等于1>>
2>: 错误信息重定向(覆盖)
2>>: 错误信息重定向(追加)
&>: 无论正确、错误信息都重定向(覆盖)
&>>: 无论正确、错误信息都重定向(追加)
[root@shell ~]# ls /boot/ asdjfasdfsdf > /opt/c.txt #只收集正确信息
[root@shell ~]# ls /boot/ asdjfasdfsdf 2> /opt/c.txt #只收集错误信息
[root@shell ~]# ls /boot/ asdjfasdfsdf &> /opt/c.txt #无论正确、错误信息都手机
六 什么是脚本
脚本:功能性的文件,通过执行这个特殊文件,从而可以实现某种功能
普通文件:诗歌、散文
一个脚本的构成:声明解释器、注释、代码正文
声明解释器:下方代码有哪个“翻译官”来翻译
注释:给人看的,对代码功能没有影响,以#开头为注释
代码正文:实现功能的代码
创建目录结构,为了好整理代码(不是必须)
[root@shell ~]# mkdir -p /root/shell/day0{1..6}
七 脚本的实现
-
代码功能:实现执行程序,输出"Hello world"功能
1、编写脚本
[root@shell ~]# vim /root/shell/day01/first.sh
#!/bin/bash #声明解释器
#This is My first shell script. #代码注释
echo "Hello World" #代码正文
2、为脚本赋予执行权限
-
当没有指定归属关系时,所有者、所属组、其他人三个归属都赋予
[root@shell ~]# chmod +x /root/shell/day01/first.sh
3、执行脚本
[root@shell ~]# /root/shell/day01/first.sh
Hello World
八 脚本执行方式
-
绝对路径(也可以切换到目录中,使用./脚本名,.表示当前路径),需要脚本具备 x 执行权限
-
指定解释器执行,不需要脚本具备x执行权限(会新开解释器)
-
source命令执行脚本,不需要脚本具备x执行权限(不会新开解释器)
验证bash执行脚本与source执行脚本的区别
[root@shell ~]# vim /root/shell/day01/test1.sh
#!/bin/bash #声明解释器
#This is a test shell script. #注释(不是必须)
exit #退出
bash执行
[root@shell ~]# bash /root/shell/day01/test1.sh #不会退出远程连接,因为会新开解释器
source执行
[root@shell ~]# source /root/shell/day01/test1.sh #会退出远程连接,因为不会新开解释器
九 变量
-
自定义变量
-
环境变量
-
位置变量
-
预定义变量
变量:以固定的字符存储会变化的值
例如:给救生员没人发一个救生衣
救生员=幸泽
救生员=立伟
1、自定义变量
要求:
-
变量名只允许出现数组、字母(区分大小写)、下划线
-
变量名不允许为纯数字
-
变量名不允许以数字开头
-
变量名不允许出现特殊符号(如:!@#$%^&*)
-
同一个变量存放不同的值,是覆盖关系
定义变量的格式:
-
变量名=值
-
调用变量:echo $变量名,echo ${变量名}
[root@shell ~]# abc=123 #定义abc变量的值为123
[root@shell ~]# echo $abc #输出变量abc的值
123
[root@shell ~]# boy=xingze #定义boy变量的职位xingze
[root@shell ~]# echo $boy #输出变量boy的值
xingze
[root@shell ~]# echo $girl #未定义变量girl,所以为空
[root@shell ~]# x=CentOS #定义变量x的值为CentOS
[root@shell ~]# echo $x #输出变量x的值
CentOS
[root@shell ~]# echo $x7.9 #输出有误,此时计算机会理解为x7是一个变量
.9
[root@shell ~]# echo ${x}7.9 #使用完整写法echo ${变量}
CentOS7.9
2、环境变量
有操作系统自己定义好的变量,这种变量往往是采用大写的方式,由操作系统维护
PATH变量:专门用于定义命令检索路径
USER变量:专门用于定义当前登录用户
UID变量:专门用于定义当前用户UID
PWD变量:专门用于定义工作目录
HOME变量:专门用于定义用户家目录
SHELL变量:专门用于定义当前用户解释器
[root@shell ~]# echo $PATH #查看命令检索路径
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@shell ~]# echo $USER #查看当前登录用户
root
[root@shell ~]# echo $UID #查看当前用户UID
0
[root@shell ~]# echo $HOME #查看当前用户家目录
/root
[root@shell ~]# echo $SHELL #查看当前用户解释器
/bin/bash
[root@shell ~]# echo $PWD #查看当前工作目录
/root
3、位置变量
用于脚本执行过程中给脚本传递参数
$n n=1,2,3,4
[root@SHELL day01]# pwd
/root/shell/day01
[root@SHELL day01]# vim vars.sh
[root@SHELL day01]# cat vars.sh
#!/bin/bash
# 测试位置变量
echo $1
echo $2
echo $3
[root@SHELL day01]# bash vars.sh aa bb cc
aa
bb
cc
[root@SHELL day01]#
#需求:写一个adduser.h的脚本 adduser.sh user pass
[root@SHELL day01]# vim adduser.sh
[root@SHELL day01]# cat adduser.sh
#!/bin/bash
# 使用位置变量添加一个用户
useradd $1
echo $2 | passwd --stdin $1
[root@SHELL day01]# bash adduser.sh tom 123
Changing password for user tom.
passwd: all authentication tokens updated successfully.
[root@SHELL day01]# id tom
uid=1000(tom) gid=1000(tom) groups=1000(tom)
[root@SHELL day01]#
4、预定义变量
$0:当前进程或脚本名
$$:当前进程号
$?:上一条命令的执行结果
$#:位置变量的个数
$*:所有的位置变量
[root@SHELL day01]# ls vars.sh
vars.sh
[root@SHELL day01]# echo $?
0
[root@SHELL day01]# ls aaaa
ls: cannot access aaaa: No such file or directory
[root@SHELL day01]# echo $?
2
[root@SHELL day01]#
[root@SHELL day01]# vim pre.sh
[root@SHELL day01]# cat pre.sh
#!/bin/bash
echo $0
echo $$
echo $#
echo $*
[root@SHELL day01]# bash pre.sh aa bb cc
pre.sh
1396
3
aa bb cc
[root@SHELL day01]# bash pre.sh 1 2 3 4
pre.sh
1409
4
1 2 3 4
[root@SHELL day01]#
十 变量的扩展应用
1、引号
-
单引号
-
双引号
[root@SHELL day01]# a=11
[root@SHELL day01]# echo $a
11
[root@SHELL day01]# echo "$a"
11
[root@SHELL day01]# echo '$a'
$a
[root@SHELL day01]#
-
反引号:将命令的执行结果赋值给变量
[root@SHELL day01]# cat /etc/passwd | grep tom
tom:x:1000:1000::/home/tom:/bin/bash
[root@SHELL day01]# a=tom:x:1000:1000::/home/tom:/bin/bash
[root@SHELL day01]# echo $a
tom:x:1000:1000::/home/tom:/bin/bash
[root@SHELL day01]# b=`cat /etc/passwd | grep tom`
[root@SHELL day01]# echo $b
tom:x:1000:1000::/home/tom:/bin/bash
[root@SHELL day01]# c=$(cat /etc/passwd | grep tom)
[root@SHELL day01]# echo $c
tom:x:1000:1000::/home/tom:/bin/bash
[root@SHELL day01]#
2、read命令
脚本运行过程中需要交互的时候使用
-
-p:提示信息
-
-t:超时时间
-
-s:屏蔽输入信息
[root@SHELL day01]# read
tom
[root@SHELL day01]# read iname
tom
[root@SHELL day01]# echo ${iname}
tom
[root@SHELL day01]# read -p "请输入主机名:" iname
请输入主机名:server7
[root@SHELL day01]# echo ${iname}
server7
[root@SHELL day01]# read -p "请输入主机名:" iname
请输入主机名:^C
[root@SHELL day01]# read -t 5 -p "请输入主机名:" iname
请输入主机名:[root@SHELL day01]#
[root@SHELL day01]# read -s -p "请输入密码:" ipass
请输入密码:[root@SHELL day01]# echo ${ipass}
123456
[root@SHELL day01]#
[root@SHELL day01]# vim read.sh
[root@SHELL day01]# cat read.sh
#!/bin/bash
read -p "请输入用户名:" iname
read -s -p "请输入密码:" ipass
useradd ${iname}
echo ${ipass} | passwd --stdin ${iname}
[root@SHELL day01]# bash read.sh
请输入用户名:jim
请输入密码:Changing password for user jim.
passwd: all authentication tokens updated successfully.
[root@SHELL day01]# id jim
uid=1001(jim) gid=1001(jim) groups=1001(jim)
[root@SHELL day01]#
3、变量作用域
-
局部作用
-
全局作用
[root@SHELL ~]# x=11
[root@SHELL ~]# echo ${x}
11
[root@SHELL ~]# bash
[root@SHELL ~]# echo ${x}
[root@SHELL ~]# exit
exit
[root@SHELL ~]# export y=22
[root@SHELL ~]# echo ${y}
22
[root@SHELL ~]# bash
[root@SHELL ~]# echo ${y}
22
[root@SHELL ~]#