Shell概述
Linux 提供的 Shell 解析器有
[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
Centos 默认的解析器是 bash
[root@localhost sy]# echo $SHELL
/bin/bash
Shell 脚本入门
-
脚本格式
脚本以#!/bin/bash 开头(指定解析器)
第一个shell脚本
创建一个 Shell 脚本,输出 helloworld
#!/bin/bash
echo "helloworld"
脚本的常用执行方式
-
采用 bash 或 sh+脚本的相对路径或绝对路径(不用赋予脚本+x 权限)
sh ./helloworld.sh bash ./helloworld.sh
-
采用输入脚本的绝对路径或相对路径执行脚本(需要添加可执行权限)
chmod +x helloworld.sh ./helloworld.sh
注意:第一种执行方法,本质是 bash 解析器帮你执行脚本,所以脚本本身不需要执行
权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限。
-
在脚本的路径前加上“.”或者 source
使用在脚本路径前加“.”或者 source 的方式,可以使脚本内容在当前shell 里执行,而无需打开子 shell!这也是为什么我们每次要修改完/etc/profile 文件以后,需
要 source 一下的原因。
开子 shell 与不开子 shell 的区别就在于,环境变量的继承关系,如在子 shell 中设置的
当前变量,父 shell 是不可见的
变量
系统预定义变量
常用系统变量
PWD、USER 等
-
查看系统变量的值
(144) root@ localhost ~/sy] $ echo $HOME /root
-
显示当前shell中所有变量 set
-
声明静态变量:readonly 变量,注意:不能 unset
自定义变量
基本变量
- 定义变量: 变量名=变量值,注意,=号前后不能有空格
- 撤销变量:unset 变量名
变量定义规则
- 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
- 等号两侧不能有空格
- 在 bash 中,变量默认类型都是字符串类型,无法直接进行数值运算。
- 变量的值如果有空格,需要使用双引号或单引号括起来。
export 变量 可把变量定义为全局变量
特殊变量
-
$n
n 为数字,$0 代表该脚本名称,$1-{10})
(150) root@ localhost ~/sy] $ vim mysh.sh (151) root@ localhost ~/sy] $ vim test.sh #!/bin/bash echo $0 echo $1 echo $2 (152) root@ localhost ~/sy] $ bash test.sh 1 2 test.sh 1 2
-
$#
获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性
-
$*
这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
-
$@
这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
-
$?
最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一
个命令正确执行;如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明
上一个命令执行不正确。
运算符
“[运算式]”
计算(2+3)* 4 的值
(154) root@ localhost ~/sy] $ echo $[(2+3)*4]
20
条件判断
[ condition ](注意 condition 前后要有空格)
常用判断条件
-
两个整数之间的比较
-eq 等于(equal) -ne 不等于(not equal)
-lt 小于(less than) -le 小于等于(less equal)
-gt 大于(greater than) -ge 大于等于(greater equal)
注:如果是字符串之间的比较 ,用等号“=”判断相等;用“!=”判断不等。
-
按照文件权限进行判断
-r 有读的权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)
-
按照文件类型进行判断
-e 文件存在(existence)
-f 文件存在并且是一个常规的文件(file)
-d 文件存在并且是一个目录(directory)
实际操作
-
helloworld.sh 是否具有写权限
(159) root@ localhost ~/sy] $ [ -w mysh.sh ] (160) root@ localhost ~/sy] $ echo $? 0
流程控制
if判断
(1)单分支
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
- 多分支
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
注意事项:
-
[ 条件判断式 ],中括号和条件判断式之间必须有空格
-
if 后要有空格
case 语句
!/bin/bash
case $1 in
"1")
echo "banzhang"
;;
"2")
echo "cls"
;;
*)
-
case 行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
-
双分号“;;”表示命令序列结束,相当于 java 中的 break。
-
最后的“*)”表示默认模式,相当于 java 中的 default。
for 循环
#!/bin/bash
sum=0
for((i=0;i<=100;i++))
do
sum=$[$sum+$i]
done
echo $sum
#!/bin/bash
#打印数字
for i in cls mly wls
do
echo "ban zhang love $i"
done
while 循环
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]
do
sum=$[$sum+$i]
i=$[$i+1]
done
echo $sum
read 读入
#!/bin/bash
read -t 7 -p "Enter your name in 7 seconds :" NN
echo $NN
-
-p:指定读取值时的提示符;
-
-t:指定读取值时等待的时间(秒)如果-t 不加表示一直等待
shell 实验练习
练习echo给变量赋值
-
把自己的名字赋值给变量name,把"是"赋值给变量is,把自己的班级名称(如网络2011)赋值给变量class,利用这几个变量用echo命令在屏幕上显示出“xxx是网络2011的学生” (xxx是你的名字)
name='陈锐' is='是' class='网络2013' echo $name$is$class的学生
-
用vi建立一个文件mysh,把上面所用到的echo命令写到文件mysh中,给予mysh文件执行的权限,然后运行mysh,看是否显示出“xxx是网络2011的学生”,如果没有显示出来,你应该怎么做让它能够显示?
vim mysh.sh
填入一下内容
#!/bin/bash name='陈锐' is='是' class='网络2013' echo $name$is$class的学生
添加可执行权限
chmod +x mysh.sh
输出
./mysh.sh
练习通过修改PS1变量来更改提示符
高亮显示
PS1="\[\e[1m\](\#) \[\e[4;31m\]\u@ \[\e[7m\]\h \w] \$ \e[m"
-
用当前路径作为提示符
PS1='$PWD>'
-
用当前日期作为提示符
PS1='\d>'
-
用当前时间作为提示符
PS1='\t>'
-
用当前路径+shell的提示符(即root为#号,普通用户为$号),并设置为重新启动后仍然生效。
find -name .bashrc
编辑.bashrc 文件
加入
PS1='$PWD>\$'
更新.bashrc文件
source .bashrc
练习find命令,全盘查找passwd文件,然后用相应的命令确认每一个passwd文件的文件类型。
find / -name passwd -ls
第一个字母为文件类型
(147) root@ localhost ~/sy] $ find / -name passwd -ls
67113279 0 dr-xr-xr-x 3 root root 0 Oct 19 23:56 /sys/fs/selinux/class/passwd
67109855 0 -r--r--r-- 1 root root 0 Oct 19 23:56 /sys/fs/selinux/class/passwd/perms/passwd
51041202 4 -rw-r--r-- 1 root root 188 Mar 31 2020 /etc/pam.d/passwd
18363676 4 -rw-r--r-- 1 root root 2308 Sep 26 05:23 /etc/passwd
练习管道的使用,完成以下要求:
- 列表分页查看/etc目录下的所有文件和子目录
ls -aR /etc|less
a表示显示所有隐藏文件,R递归显示文件夹当中的文件
-
利用tar命令和gzip命令完成对/home目录的打包和压缩,不准使用tar中的z参数
tar -cvf home.tar.gz /home/*
编写一个shell小程序
对一个目录实现交互式的备份压缩。(根据屏幕的提示选择压缩的方式是gzip还是bzip2、输入备份目录的路径,备份压缩的文件名等)
#!/bin/bash
echo "欢迎使用文件压缩系统"
read -p "输入压缩路径:" path
echo "请选择压缩类型序号 1.gzip 2.bzip"
read choice
if [ $choice -eq 1 ]
then
tar -cvPf your.tar.gz $path
elif [ $choice -eq 2 ]
then
tar -jcvPf your.tar.gz $path
else
ehco "选择错误重新选择"
fi
echo "压缩结束"
不加p,绝对路径报错