文章目录
一、 shell脚本与编程规范
在一些复杂Linux维护工作中,会有大量的重复性工作和交互操作,如果一直用人工的方式操作,不但费时费力,还容易出错,而编写一个shell脚本程序就可以很好的解决这个问题。
1.1 shell脚本
shell脚本(Shell Script)就是将一个要执行的命令按顺序保存在一个文本文件中,并给该文件一个可执行权限,方便一次性执行的一个程序文件。
shell脚本主要是方便管理员进行设置或者管理用的。但是它比Windows下的批处理更强大,比用其他编程程序编辑的程序效率更高,它使用了Linux/Unix下的命令。
1.2 shell编程规范
shell介于操作系统内核与用户之间,充当这“翻译官”的角色,负责接收用户输入的操作指令并进行解释,传递给内核执行,执行输出结果。
我们可以通过查看/etc/shells可以了解当前系统所支持的shell脚本种类。
/bin/bash是目前大多数Linux版本默认的shell脚本。
一个合格的shell脚本程序应该遵循标准的脚本结构,而且能够输出友好的提示信息、更容易让人读懂。
shell脚本的第一行是“#!/bin/bash”,这是一行特殊的脚本声明,表明此后的语句都是用/bin/bash程序来执行;以“#”开头的语句表示注释信息;echo命令用于输出字符串,让脚本更容易让人读懂。
没有经过优化的简单shell脚本
[root@localhost ~]# vi first.sh
#!/bin/bash 声明环境变量
cd /etc 到/etc目录下
pwd 打印当前位置
grep "bash" /etc/passwd | wc -l 筛选出 /etc/passwd文件中含bash的行数
执行结果如下
优化过后
[root@localhost ~]# vi first.sh
#!/bin/bash
cd /etc
echo "当前目录位于:"
pwd
echo "/etc/passwd文件中含有bash的行数为:"
grep "bash" /etc/passwd | wc -l
优化后的结果
1.3 shell脚本的执行
执行的方式有三种,我以first.sh脚本文件为例,这里脚本文件的绝对路径与相对路径都可以使用。
- 第一种方法:./ first.sh
- 第二种方法:sh first.sh
- 第三种方法:source first.sh 或者 . first.sh
三种方法的不同点在于:
- 第一种方法需要被赋予可执行权,也就是x权限。
- 第二种方法可以不需要执行权限
- 第三种方法也可以不需要执行权限,但是环境会随着脚本中的内容而变化。
二、 管道与重定向
管道与重定向主要是帮助我们对信息进行提取与过滤。
2.1 管道操作
对于已经接触脚本的朋友,管道符号一定不会陌生,管道符号“
|”在我们键盘enter的上方。位于管道符号左侧的命令输出的结果作为右侧命令的输入(处理对象),就拿上面写好的脚本"grep “bash” /etc/passwd | wc -l "的管道符号为例子。
管道符号左边的grep “bash” /etc/passwd就是筛选出/etc/passwd中含有"bash"字符串的文件,这些文件作为"wc -l"命令的作用对象,也就是将前面输出的文件的行数统计出来。
管道符号的基本使用格式
command命令1 | command命令2 | command命令3 ...|command命令n
管道符号不限使用的次数,从左往右按顺序依次执行过去。
2.1.1 管道符号与正则表达式的应用实例
我们在排错的过程中,通常只是想看到关键的信息,对于那些很长的内容,我们就可以将管道符号与正则表达式结合在一起使用,可以更方便我们过滤关键信息。
[root@localhost ~]# grep "bash$" /etc/passwd 查找/etc/passwd文件中以"bash"结尾的文件
root:x:0:0:root:/root:/bin/bash
shi:x:1000:1000:shi:/home/shi:/bin/bash
我们只需要看筛选出文件中的第一列和第七列的内容
[root@localhost ~]# grep "bash$" /etc/passwd | awk -F: '{print $1,$7}' awk为正则表达式,作用是以”:“作为分隔,输出第一和第七区域的字符串,-F是指定分隔符号(未指定时表示以空格和制表符分隔)
root /bin/bash
shi /bin/bash
如果我们想要查看挂载的/dev/cdrom已用空间所占的百分比,我们同样可以使用正则表达式与管道符号
[root@localhost ~]# df -Th
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/sda3 xfs 295G 8.5G 287G 3% /
devtmpfs devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs tmpfs 1.9G 13M 1.9G 1% /run
tmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/sr0 iso9660 4.3G 4.3G 0 100% /mnt
/dev/sda1 xfs 1014M 174M 841M 18% /boot
tmpfs tmpfs 378M 4.0K 378M 1% /run/user/42
tmpfs tmpfs 378M 40K 378M 1% /run/user/0
[root@localhost ~]# df -Th |grep "sr0"| awk '{print $6}'
100%
2.2 重定向操作
用户通过操作系统处理信息的过程中,包括以下几类交互设备文件:
- 标准输入(STDIN):默认的设备是键盘,文件编号是0,命令将从标准输入文件中读取在执行过程中需要的输入数据。
- 标准输出(STDOUT):默认的设备是显示器,文件编号为1,命令将执行后的输出结果发送到标准输出文件。
- 标准错误(STDERR):默认的设备是显示器,文件编号为2,命令将执行期间的各种错误信息发送到标准错误文件。
- 在实际的Linux系统维护中,可以改变输入、输出内容的方向,而不使用默认的标准输入、输出设备(键盘和显示器),这种操作叫做”重定向“。
2.2.1 重定向输入
重定向输入指的是将命令中接受输入的途径由默认的键盘改为指定的文件,而不是等待从键盘输入。
重定向输入使用”<“操作符。
重定向符号可以用来为用户设置密码。
[root@localhost ~]# vi passwd.txt
Abc123
[root@localhost ~]# passwd --stdin shi < passwd.txt
更改用户 shi 的密码 。
passwd:所有的身份验证令牌已经成功更新。
这种设置密码的方式免去了之前用”passwd“命令的两次输入密码的过程,减少了交互过程,提高了脚本的执行效率。
2.2.2 重定向输出
重定向输出是指将命令输出的结果保存到指定的文件中,不会显示在显示器的屏幕上。重定向输出使用“>”或“>>”符号,分别表示覆盖文件、追加文件。
当重定向输出的目标文件存在时,使用“>”会覆盖原文件,“>>”就会追加到文件的尾部;如果目标文件不存在,就会新建一个文件,将输出的结果写入新文件。
[root@localhost opt]# ls
httpd-2.4.25 httpd-2.4.25.tar.gz rh
[root@localhost opt]# df -Th | grep sr0 | awk '{print $6}'
100%
[root@localhost opt]# df -Th | grep sr0 | awk '{print $6}' > new.txt 创建了一个新文件,并将输出结果写进去
[root@localhost opt]# cat new.txt
100%
[root@localhost opt]# df -Th | grep sda1 | awk '{print $7}'
/boot
[root@localhost opt]# df -Th | grep sda1 | awk '{print $7}' > new.txt 覆盖了原来的文件
[root@localhost opt]# cat new.txt
/boot
[root@localhost opt]# df -Th | grep sr0 | awk '{print $7}' >> new.txt 追加到文件的底部
[root@localhost opt]# cat new.txt
/boot
/mnt
2.2.3 错误重定向
错误重定向是指将执行命令过程中出现的错误信息保存到指定的文件中,不显示在屏幕上。错误重定向符是“2>”,2是指错误文件的编号。也就是标准错误(STDERR)。
错误重定向符“2>”与重定向输出符号“>”用法相似,都会覆盖原来文件,如果要追加到文件中,可以使用“2>>”操作符。
在我们工作中,一般用这个来收集程序执行的错误信息,以便于排错;对于shell脚本,我们也可以将无关紧要的消息放到/dev/null中,保持清洁。/dev/null就像是一个黑洞,任何文件进去都会被消化掉。
[root@localhost opt]# ls
httpd-2.4.25 httpd-2.4.25.