Shell解释器介绍
Shell编程:
就是把我们写的Linux命令封装到1个文件中, 这个文件就叫: Shell脚本. 它是可以被执行的.
从编写, 到执行的完整过程, 称之为:; Shell编程.
# Shell脚本的执行, 底层需要用到Shell解释器, Linux的众多发行版, 默认的Shell解释器是: /bin/bash
[root@node1 ~]# cat /etc/shells # 查看当前Linux系统支持哪些Shell解释器
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
[root@node1 ~]# echo $SHELL # 查看当前Linux系统使用的, 默认的Shell解释器
/bin/bash
[root@node1 ~]#
# 扩展: Shell中的变量是一种很"弱"的变量, 它分为: 用户变量, 环境变量, 特殊变量.
# 强弱的划分依据是: 对数据的数据类型划分是否精细.
精细: 强类型, 例如: SQL, Java,
不精细: 弱类型, python, shell
# Linux中定义变量的格式
变量名=变量值
# 变量的注意事项
1. 定义变量的时候, 等号两端没有空格.
2. 变量名可以由英文字母, 数字, 下划线组成, 其中: 数字不能开头.
3. 变量名不要和关键字重名, 且最好做到见名知意.
4. 如果变量值中间有空格, 要用引号包裹变量值, 建议使用: 双引号.
5. 变量值中可以用\表示转移符, 例如: \n就表示换行, \t表示制表符(相当于4个空格)
1.Shell变量--用户变量
变量入门(用户变量)
# 定义变量的格式: 变量名=变量值
[root@node1 ~]# name=zhangsan # 定义name变量, 变量值是: zhangsan
[root@node1 ~]# echo name # 输出name, 没写$, 表示输出内容
name
[root@node1 ~]# echo ${name} # 输出变量name的值.
zhangsan
[root@node1 ~]# echo $name # 同上, 如果不涉及到拼接等复杂操作, 可以省略大括号.
zhangsan
[root@node1 ~]# echo $name是我的名字 # 拼接, 输出.
zhangsan是我的名字
[root@node1 ~]# echo $name23 # 拼接, 输出. 没加大括号, 所以 name23变成1个整体了.
[root@node1 ~]# echo ${name}23 # 这个才是正常的拼接, 输出.
zhangsan23
[root@node1 ~]# name=lisi # 重新修改name变量的值, 为: lisi
[root@node1 ~]# echo $name # 输出
lisi
[root@node1 ~]# unset name # 删除name变量, 相当于没有定义它, 后续不能用了.
# 或者本次会话断开, 变量也会被释放.
[root@node1 ~]# echo $name # 因为变量name已经删除了, 这里打印的结果是: 空
[root@node1 ~]# age=18
[root@node1 ~]# readonly age # 设置变量age为 只读变量(只能用, 不能改, 不能删)
[root@node1 ~]# age=20 # 尝试修改只读变量, 报错
-bash: age: 只读变量
[root@node1 ~]# echo $age
18
[root@node1 ~]# unset age # 尝试删除只读变量, 报错
-bash: unset: age: 无法反设定: 只读 variable
关于引号的问题
# 细节: 双引号, 可以引用变量的值, 单引号, 表示原样输出.
[root@node1 ~]# name=zhangsan lisi # 定义变量, 变量值有空格, 报错
-bash: lisi: 未找到命令
[root@node1 ~]# name='zhangsan lisi' # 用引号包裹变量值即可.
[root@node1 ~]# echo $name
zhangsan lisi
[root@node1 ~]# new_name='$name wangwu' # 如果单引号包裹, 原样输出.
[root@node1 ~]# echo $new_name
$name wangwu
[root@node1 ~]# new_name2="$name wangwu" # 如果是双引号包裹, 可以引用变量的值.
[root@node1 ~]# echo $new_name2
zhangsan lisi wangwu
[root@node1 ~]#
[root@node1 ~]# str='This's zhangsan' # 报错
> 123'
-bash: $'zhangsan\n123': 未找到命令
[root@node1 ~]# str="This's zhangsan" # 如果内容涉及到引号了, 就: 外双内单, 外单内双.
[root@node1 ~]# echo $str
This's zhangsan
2.Shell变量--环境变量
# 配置环境变量的目的
在任意的路径下, 都能使用(环境变量中)配置好的内容.
# 例如:
之所以能在任意的路径下使用 cd, ls等命令, 是因为 /usr/bin /usr/sbin已经配置到path环境变量中了.
# 如何查看环境变量
[root@node1 ~]# env
XDG_SESSION_ID=233
HOSTNAME=node1
TERM=linux
SHELL=/bin/bash
HADOOP_HOME=/export/server/hadoop
HISTSIZE=1000
SSH_CLIENT=192.168.88.1 59719 22
SSH_TTY=/dev/pts/0
name=hangge # 手动设置的环境变量
USER=root
age=18 # 手动设置的环境变量
MAIL=/var/spool/mail/root
PATH=/export/server/jdk1.8.0_241/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/export/server/hadoop/bin:/export/server/hadoop/sbin:/root/bin
PWD=/root
JAVA_HOME=/export/server/jdk1.8.0_241
LANG=zh_CN.UTF-8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
CLASSPATH=.:/export/server/jdk1.8.0_241/lib
SSH_CONNECTION=192.168.88.1 59719 192.168.88.161 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env
# 如何设置环境变量
# 方式1: 临时设置, 会话结束, 自动断开.
export 变量名=变量值 # 例如: export name=zhangsan
# 方式2: 永久设置.
vim /etc/.bashrc # 只针对于当前用户有效.
vim /etc/profile # 针对于所有用户有效, 推荐.
# 细节: 设置完之后, 需要刷新下配置文件, 才能生效.
思路1: 登出(ctrl + d), 重新登入
思路2: 命令实现, 即: source /etc/profile
# 扩展, 取消Linux的邮箱校验.
vim /etc/profile
按G到文件的末尾, 然后按o, 向下插入一行, 然后输入 unset MAILCHECK
按esc, 输入 :wq 保存退出.
source /etc/profile 刷新即可.
3.关于Linux的符号问题
# 如何执行Linux命令
# 格式1: `Linux命令`
# 格式2: $(Linux命令)
[root@node1 ~]# p=`pwd` # 执行Linux命令pwd, 将其执行结果赋值给变量 p
[root@node1 ~]# echo $p # 输出变量p的结果
/root
[root@node1 ~]# p2=$(pwd) # 效果同上
[root@node1 ~]# echo $p2
/root
# 大括号的作用, 用于引用变量的值.
echo ${name}是我的名字
# 如何执行数学运算?
# 格式1: $[3 + 5]
# 格式2: $((3 + 5))
[root@node1 ~]# echo $[3+5]
8
[root@node1 ~]# echo $[ 3 + 5 ]
8
[root@node1 ~]# echo $[ 3 * 5 ]
15
[root@node1 ~]# echo $[ 3 / 5 ]
0
[root@node1 ~]# echo $[ 3 % 5 ]
3
[root@node1 ~]# echo $[ 10 % 3 ]
1
[root@node1 ~]# echo $[ 10 - 3 ]
7
[root@node1 ~]# echo $((3+5))
8
[root@node1 ~]# echo $(3+5)
-bash: 3+5: 未找到命令
[root@node1 ~]#
4.如何编写以及执行shell脚本
编写Shell脚本
1. 在后缀名为.sh的文件中进行编写, 当然, 文件后缀名可以是其它的, 建议是 .sh
2. 文件的第一行建议是 #!/bin/bash 表示指定Shell解释器.
3. 除了第1行的#外, 其它行的#都是 注释.
示例: 编写Shell脚本
vim my.sh
#!/bin/bash
echo '这是我的第1个Shell脚本'
# 记得 :wq保存退出
执行Shell脚本
# 方式1: sh 脚本名.sh
sh my.sh # 不需要对 my.sh脚本 有执行权.
# 方式2: source 脚本名.sh
source my.sh # 不需要对 my.sh脚本 有执行权.
# 方式3: 相对路径
./my.sh # 要有执行权
# 方式4: 绝对路径
/root/my.sh # 要有执行权
-
# 方式1: sh 脚本名.sh sh my.sh # 不需要对 my.sh脚本 有执行权. # 方式2: source 脚本名.sh source my.sh # 不需要对 my.sh脚本 有执行权. # 方式3: 相对路径 ./my.sh # 要有执行权 # 方式4: 绝对路径 /root/my.sh # 要有执行权
5.Shell案例-输出姓名,年龄,性别
版本1: 固定值的方式
vim my2.sh
#!/bin/bash
# 1.定义变量, 记录某个人的姓名
name='乔峰'
# 2.定义变量, 记录某个人的年龄
age=33
# 3.定义变量, 记录某个人的性别
gender="male"
# 4.打印该学员的信息
echo "我叫${name}, 今年${age}岁了, 我的性别是:${gender}"
# 执行
sh my2.sh
# 弊端: 值都写死了, 不灵活, 实际开发, 我们可以给Shell脚本 动态传参.
-
版本2: 动态传参的方式
vim my3.sh #!/bin/bash # 1.定义变量, 记录某个人的姓名 name=$1 # 2.定义变量, 记录某个人的年龄 age=$2 # 3.定义变量, 记录某个人的性别 gender=$3 # 4.打印该学员的信息 echo "我叫${name}, 今年${age}岁了, 我的性别是:${gender}" # 5.打印其它信息. echo "文件名是: $0" echo "所有的参数为: $*" echo "参数总数为: $#" # 执行 参1 参2 参3 参4 参5 [root@node1 ~]# sh my3.sh 段誉 19 男 大理市 六脉神剑 我叫段誉, 今年19岁了, 我的性别是:男 文件名是: my3.sh 所有的参数为: 段誉 19 男 大理市 六脉神剑 参数总数为: 5