文章目录
一、shell的编程规范与变量
前言:
与c语言这种编程性语言不同,shell是一种解释性语言
shell的作用——充当命令解释器,“翻译官”
- 它介于操作系统内核与用户之间,负责接收用户输入的操作指令并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。
一、shell脚本基础
1.Shell脚本的概述
- 将要执行的命令按顺序保存到一个文本文件
- 给该文件可执行权限
- 可结合各种Shell控制语句以完成更复杂的操作
2.Shell脚本应用场景
- 重复性操作
- 交互性任务
- 批量事务处理
- 服务运行状态监控
- 定时任务执行
- ……
3.shell脚本的作用
(3.1)shell脚本的作用:命令解释器,翻译官
1、介于系统内核与用户之间,负责解释命令行
2、shell 控制Linux内核,内核态会加载系统硬件提供支持,然后输出信息
3、shell 也可以通过控制应用程序,再进行控制Linux内核
4、应用程序
5、内核放在boot中,boot还存放的GRUB菜单
4.Linux中常见的shell
用户登陆的shell
- 登陆后默认使用的shell程序,一般为 /bin/bash
- 不同shell的内部指令、运行环境等会有所区别
[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
bash:基于gun的框架下发展的shell
csh:类似c语言的shell
tcsh:整合了csh提供了更多功能
sh:已经被bash替换
nologin:会让用户无法登陆
5.什么是shell脚本?
- 就是将命令按顺序一一列出,最后自动执行
- 执行需要权限,也可以直接调用
- 脚本并不复杂,通用脚本环境改变后依然可以使用的脚本
构成
1、脚本申明(解释器):第一行开头“#!/bin/bash”,表示此行以下的代码语句是通过/bin/bash程序来解释执行的。
#!/bin/bash为默认的解释器还有其他类型的解释器,(如#!/bin/python #!/bin/expect)
2、注释信息:以#开头的语句表示为注释信息
3、可执行语句:比如echo命令用于输出“ ”之间的字符串
[root@localhost rui]# vim 1.sh
#!/bin/bash
echo "hello world"
[root@localhost rui]# bash 1.sh
hello world
6.脚本的执行逻辑
脚本执行逻辑
- 顺序执行:程序按从上到下顺序执行
- 选择执行:程序执行过程中,根据筛选的条件,选择不同分支继续执行
- 循环执行:程序执行过程中重复执行程序
执行方式
1、指定路径去执行文件(需要权限)
[root@localhost ~]# chmod +x /root/frist.sh 加权限
指定相对路径./frist.sh
指定绝对路径/root/frist.sh
2、指定解释器去执行(不需要权限)
[root@localhost ~]# bash frist.sh
3.source 脚本文件路径
[root@localhost ~]# source frist.sh
7.脚本的错误
- 命令错误,命令出错并不会影响接下来的命令继续
- 语法错误,后续命令不继续执行
- 逻辑错误,只能自己去筛查
bash -n 脚本名称(不在当前目录下加绝对路径) #查询语法错误
bash -x 脚本名称(不在当前目录下加绝对路径) #追踪运行过程,将过程展示出来(逻辑错误)
例如:
#编辑一个简单的求和
[root@localhost ~]# vim 1.sh
#!/bin/bash
sum=0
for i in {1..100}
do
sum=$[i+sum]
done #有do就要有done
echo "求和结果是$sum"
[root@localhost ~]# bash 1.sh
求和结果是5050
总结:脚本错误常见的有三种区别
1、命令错误,默认后续的命令还会继续执行,用bash -n 无法检查出来 ,可以使用 bash -x 进行观察
2、语法错误,会导致后续的目录不继续执行,可以用bash -n检查错误,提示的出错行数不一定是准确的
3、逻辑错误,只能用bash -x进行
8.操作
顺序执行,一条一条往下执行
写出一个自动搭建本地yum仓的脚本
[root@localhost ~]# vim yum.sh
#!/bin/bash
mkdir /ky15
mount /dev/sr0 /ky15 &>/dev/null#重定向
cd /etc/yum.repos.d
mkdir bak
mv *.repo bak
echo "[abc]
name=centos7
baseurl=file:///ky15
gpgcheck=0">abc.repo
#将内容导入abc.repo
yum clean all &>/dev/null
#清理缓存,弹出信息导入空
yum install httpd -y
#安装一个httpd测试
[root@localhost ~]# bash yum.sh
二、重定向与管道操作
- 交互式硬件设备
- 标准输入:从该设备接收用户输入的数据
- 标准输出:通过该设备向用户输出数据
- 标准错误:通过该设备报告执行出错信息
类型 | 设备文件 | 文件描述编号 | 默认设备 |
---|---|---|---|
标准输入 | /dev/stdin | 0 | 键盘 |
标准输出 | /dev/stdout | 1 | 显示器 |
标准错误输出 | /dev/stderr | 2 | 显示器 |
2.什么是重定向?
意思就是,不通过标准输出到屏幕上,输出到你指定的位置
重定向操作
类型 | 操作符 | 用途 |
---|---|---|
重定向输入 | < | 从指定的文件读取数据,而不是从键盘输入 |
重定向输出 | > | 将输出结果保存到指定的文件(覆盖原有内容) |
>> | 将输出结果追加到指定的文件尾部 | |
标准错误输出 | 2> | 将错误信息保存到指定的文件(覆盖原有内容) |
2>> | 将错误信息追加到指定的文件中 | |
混合输出 | &> | 将标准输出、标准错误的内容保存到同一个文件中 |
#不能将正确和错误一起显示出来
[root@localhost ~]# ls /data /xxx > /data/all.log 2>&1
[root@localhost ~]# ls /data /xxx 2> /data/all.log 1>&2
[root@localhost ~]# ls /data /xxx &> /data/all.log
[root@localhost ~]# ls /data /xxx >& /data/all.log 错误的
多行重定向
[root@localhost ~]# cat > 22.txt
agsg
agsd
sss
^C
#需要回车才能写入
[root@localhost ~]# cat >33.txt <<EOF
> 111
> 222
> 333
> 444
> EOF
#EOF是个标记符,没有特殊含义,用别的字符效果也一样,只要开头和结尾一样就行
2.3管道符 |
作用:将左侧的命令输出结果,作为右侧命令的输入(处理对象)可以叠加使用
例如:
#提取自己机器的IP地址
[root@localhost ~]# ifconfig ens33|awk /netmask/'{print $2}'
192.168.xxx.xxx
#更改用户的密码
[root@localhost ~]# echo "233233" |passwd --stdin lisi
更改用户 lisi 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# grep "/bin/bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
rui:x:1000:1000:rui:/home/rui:/bin/bash
lisi:x:1001:1001::/home/lisi:/bin/bash
[root@localhost ~]#
[root@localhost ~]# grep "/bin/bash$" /etc/passwd | awk -F: '{print $1,$7}'
#输出第一段字符和第七段字符
root /bin/bash
rui /bin/bash
lisi /bin/bash
三、变量
3.1常见shell变量的类型
包括:
自定义变量:由用户自己定义,修改和使用
环境变量:由系统维护,用于设置工作环境
只读变量:只可以读取不可以更改
位置变量:通过命令行给脚本传递参数
预定义变量:Bash中内置的一类变量,不能修改
系统内置变量:PATH,UID,HOSTNAME
3.2命令要求
- 区分大小写
- 不能使用程序中的保留字和内置变量:如:if, for,hostname
- 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反
- 不要使用内置的变量,使用英文尽量使用词义通俗易懂,PATH
- 大驼峰StudentFirstName
- 小驼峰studentFirstName
- 下划线: student_name
name='value'
变量名=变量值
直接字串:name='root'
变量引用:name="$USER"
命令引用:name=`COMMAND` 或者 name=$(COMMAND)
#注:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存
#脚本中的变量随着脚本结束,会自动删除
变量引用:
$name
${name}
弱引用和强引用
"$name " 弱引用,其中的变量引用会被替换为变量值
'$name ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
- 赋值时使用双引号("")可以直接调用变量
- 赋值时使用单引号(’’) 只 会 被 认 为 是 字 符 只会被认为是字符 只会被认为是字符 不会调用变量
- 赋值时使用(``反撇在tab上面)命令替换,提取命令执行后的输出结 果$() 用法相同
- {}可以分隔变量值
3.3read -p
从键盘输入的内容变成变量
方法1
[root@localhost ~]# read -p "现在的时间是" time
现在的时间是9点
[root@localhost ~]# echo $time
9点
方法2
[root@localhost ~]# vim 222.sh
#!/bin/bash
echo -n "输入你的信息"
read info
echo $info
[root@localhost ~]# bash 222.sh
输入你的信息333
333
3.4变量作用范围
默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再作用。
可以通过内部命令export将指定的变量到处为全局变量,使用户定义的变量在所有子shell环境中可以继续使用
方法:
- 格式1:export 变量名
- 格式2:export 变量名=变量值
使用pstree可以查看shell的环境
输入bash进入子shell
ctrl+D组合exit 退出子shell
3.5整数变量的运算
常用运算符
加法运算:+
减法运算:-
乘法运算:\*
除法运算:/
整数取余:%
注意格式
运算符两边要有空格,缺少空格无法运算
3.6环境变量
1.由系统提前创建,用来设置用户的工作环境
2.可以使用env查看环境变量
3.需要记住的常用环境变量
$USER 表示用户名称
$HOME 表示用户的宿主目录
$LANG 表示语言和字符集
$PWD 表示当前所在工作目录
$PATH 表示可执行用户程序的默认路径
环境变量:
- 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量
- 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程
- 一般只在系统配置文件中使用,在脚本中较少使用
总结
初学shell,有点复杂,需要花点时间去整理并实验,验证它的效果。