Bash Shell简介
与GNU Linux的风格类似,shell有很多种类,兼容性各不相同. CentOS中的默认shell称为Bash或Bourne Again Shell. Bash shell是由Stephen Bourne开发的现代修订版Bourne Shell. Bash是Ken Thompson和Dennis Ritchie在贝尔实验室开发的Unix操作系统上的原始Thompson Shell的直接替代品(Stephen Bourne也受雇于贝尔实验室)
每个人都喜欢贝壳和每个都有它的优点和困难.但在大多数情况下,Bash将成为所有Linux发行版中的默认shell,并且最常用.根据经验,每个人都希望探索和使用最适合他们的外壳.但与此同时,每个人都希望掌握Bash shell.
其他Linux shell包括:Tcsh,Csh,Ksh,Zsh和Fish.
在专家级开发使用任何Linux shell的技能对于CentOS管理员来说非常重要.正如我们之前提到的,与Windows不同,Linux的核心是命令行操作系统. shell只是一个用户界面,允许管理员(或用户)向操作系统发出命令.如果一个Linux系统管理员是一个航空公司的飞行员,那么使用它将类似于让飞机脱离自动驾驶并抓住手动控制以获得更多机动飞行.
Linux shell,如Bash,在计算机科学术语中被称为命令行解释器. Microsoft Windows还有两个命令行解释器,称为DOS(不要与原来的DOS操作系统混淆)和PowerShell.
大多数现代shell如Bash提供构造允许更复杂的 shell脚本自动执行常见任务和复杂任务.
构造包括 :
脚本流程控制(ifthen和其他)
逻辑比较操作(大于,小于,相等)
循环
变量
参数定义操作(类似于带命令的开关)
使用Shell脚本与脚本语言
通常在考虑执行任务时,管理员会问自己:我应该使用shell脚本还是脚本语言,如Perl,Ruby或Python?
这里没有设定规则. shell与脚本语言之间只有典型的区别.
Shell
Shell允许使用Linux命令,例如 sed , grep , tee , cat 以及Linux操作系统上所有其他基于命令行的实用程序.实际上,几乎任何命令行Linux实用程序都可以在shell中编写脚本.
使用shell的一个很好的例子是检查DNS解析主机列表的快速脚本.
我们的简单Bash脚本检查DNS名称 :
#!/bin/bash for name in $(cat $1); do host $name.$2 | grep "has address" done exit
用于测试DNS分辨率的小字列表<
dns www test dev mail rdp remote
针对google.com域的输出 :
[rdc@centos ~]$ ./dns-check.sh dns-names.txt google.com-doing dnsdns.google.com has address 172.217.6.46-doing wwwwww.google.com has address 172.217.6.36-doing test-doing dev-doing mailgooglemail.l.google.com has address 172.217.6.37-doing rdp-doing remote[rdc@centos ~]$
在我们的shell中利用简单的Linux命令,我们能够制作一个简单的5行脚本来审核单词列表中的DNS名称.即使使用了很好实现的DNS库,这在Perl,Python或Ruby中也需要相当长的时间.
脚本语言
脚本语言将在shell之外提供更多控制权.上面的Bash脚本使用Linux host 命令的包装器.如果我们想要做更多的事情并使我们自己的应用程序(如 host )在shell外部进行交互,该怎么办?这就是我们使用脚本语言的地方.
此外,通过高度维护的脚本语言,我们知道我们的操作大部分都可以在不同的系统中运行.例如,Python 3.5将适用于运行Python 3.5且安装了相同库的任何其他系统.不是这样,如果我们想在Linux和HP-UX上运行我们的BASH脚本.
有时,脚本语言和强大的shell之间的界限可能会模糊不清.可以使用Python,Perl或Ruby自动执行CentOS Linux管理任务.这样做真的很平常.此外,富裕的shell脚本开发人员在Bash中创建了一个简单但功能强大的Web服务器守护程序.
凭借脚本语言和自动执行shell任务的经验,CentOS管理员将会能够在需要解决问题时快速确定从哪里开始.使用shell脚本启动项目是很常见的.然后,随着项目进展到脚本(或编译)语言变得更加复杂.
此外,可以为项目的不同部分使用脚本语言和shell脚本.一个例子可能是用于刮取网站的Perl脚本.然后,使用shell脚本使用 sed , awk 和 egrep 进行解析和格式化.最后,使用PHP脚本使用Web GUI将格式化数据插入MySQL数据库.
有了shell背后的一些理论,让我们开始使用基本构建块来自动化Bash shell中的任务在CentOS.
输入输出和重定向
将stdout处理为另一个命令 :
[rdc @ centos~] $ cat~/output.txt | wc -l 6039 [rdc @ centos~] $
上面,我们已经通过 cat'sstoud 到 wc 以使用 pipe 字符进行处理. wc 然后处理 cat 的输出,将output.txt的行数打印到终端.将 pipe 字符视为从一个命令传递输出的"管道",由下一个命令处理.
以下是要记住的关键概念处理命令重定向 :
Number | 文件描述符 | 字符 |
---|---|---|
0 | 标准输入 | < |
1 | 标准输出 | > |
2 | 标准错误 | |
追加stdout | >> | |
指定重定向 | & | |
将标准输出管道输入stdin | | |
我们在第一章中介绍了这一点,但没有真正谈论重定向或分配重定向.在Linux中打开终端时,你的shell被视为的默认目标;
标准输入< 0
标准输出> 1
标准错误2
让我们看看这是如何工作的去;
[rdc @ centos~] $ lsof -ap $ BASHPID -d 0,1,2 COMMAND PID USER ** FD ** TYPE DEVIZ SIZE/OFF NODE NAME bash 13684 rdc ** 0u ** CHR 136,0 0t0 3/dev/pts/0 bash 13684 rdc ** 1u ** CHR 136,0 0t0 3/dev/pts/0 bash 13684 rdc ** 2u ** CHR 136,0 0t0 3/dev/pts/0 [rdc @ centos~]
/dev/pts/0 是我们的伪终端. CentOS Linux对此进行了研究,并认为我们的开放式终端应用程序就像一个真正的终端,键盘和显示器通过串行接口插入.但是,像虚拟机管理程序将硬件抽象到操作系统/dev/pts 将我们的终端抽象为应用程序.
从上面的 lsof 命令,我们可以在 FD 列下看到所有三个文件描述符都设置为我们的虚拟终端(0,1,2).我们现在可以发送命令,查看命令输出,以及与命令相关的任何错误.
以下是STDIN和STDOUT的示例;
STDOUT
[root@centosLocal centos]# echo "I am coming from Standard output or STDOUT." >output.txt && cat output.txtI am coming from Standard output or STDOUT. [root@centosLocal centos]#
也可以同时发送 stdout 和 stderr 分隔文件 :
bash-3.2# find / -name passwd 1> good.txt 2> err.txtbash-3.2# cat good.txt/etc/pam.d/passwd/etc/passwdbash-3.2# cat err.txt find: /dev/fd/3: Not a directoryfind: /dev/fd/4: Not a directorybash-3.2#
搜索整个文件系统时,遇到两个错误.每个都被发送到一个单独的文件供以后阅读,而返回的结果被放入一个单独的文本文件.
将 stderr 发送到文本文件可能很有用当做一些输出大量数据到终端的东西,比如编译应用程序.这将允许细读可能从终端回滚历史中丢失的错误.
将STDOUT传递给文本文件时的一个注意事项是>> 和> .双">>"将附加到文件,而单数形式将破坏文件并写入新内容(因此所有以前的数据都将丢失).
STDIN
[root@centosLocal centos]# cat < stdin.txtHello,I am being read form Standard input, STDIN.[root@centosLocal centos]#
在上面的命令中,文本文件 stdin.txt 被重定向到 cat 命令,该命令将其内容回显到 STDOUT .
管道符"|"
管道字符将获取第一个命令的输出,将其作为输入传递给下一个命令,允许辅助命令对输出执行操作.
现在,让我们将猫的stdout"管道"到另一个命令 :
[root @ centosLocal centos] #cat output.txt | wc -l 2 [root @ centosLocal centos]#
上面, wc 执行计算从管道传递的 cat 的输出.过滤 grep 或 egrep :
[root@centosLocal centos]# egrep "^[0-9]{4}$" /usr/dicts/nums | wc -l 9000 [root@centosLocal centos]#
在上面的命令中,我们将每4位数传递给 wc 来自一个文本文件,其中包含通过 egrep 过滤器传递的65535中的所有数字.
使用&
可以使用& 字符重定向输出.如果我们想将输出STDOUT和STDERR都指向同一个文件,它可以完成如下:<
[root@centosLocal centos]# find / -name passwd > out.txt 2>&1[root@centosLocal centos]# cat out.txt find: /dev/fd/3: Not a directory find: /dev/fd/4: Not a directory /etc/passwd[root@centosLocal centos]#
使用& 字符重定向的方式如下:首先,输出重定向到 out.txt .其次,STDERR或文件描述符2被重新分配到与STDOUT相同的位置,在本例中为 out.txt .
重定向非常有用并且派上用场同时解决操作大型文本文件时的问题,编译源代码,在shell脚本中重定向输出,以及发出复杂的Linux命令.
虽然功能强大,但对于较新的CentOS,重定向会变得复杂管理员.对Linux论坛(例如Stack Overflow Linux)的实践,研究和偶尔的问题将有助于解决高级解决方案.
Bash Shell构造
现在我们对 Bash shell 的工作方式有了一个很好的了解,让我们学习一些常用的基本结构来编写脚本.在本节中,我们将探讨 :
变量
循环
条件
循环控制
读取和写入文件
基本数学运算
BASH故障排除提示
与专用脚本语言相比,BASH可能有点棘手. BASH脚本中一些最大的问题是来自错误地转义或不转义传递给shell的脚本操作.如果您已经查看了几次脚本并且它没有按预期工作,请不要担心.这对于那些每天使用BASH创建复杂脚本的人来说很常见.
快速搜索Google或在专家Linux论坛注册以提出问题将导致快速解决问题.很可能有人遇到了确切的问题并且已经解决了.
BASH脚本编写是一种很好的方法,可以快速创建功能强大的脚本,从自动执行管理任务到创建有用的工具.成为专家级BASH脚本开发人员需要时间和练习.因此,尽可能使用BASH脚本,它是CentOS管理工具箱中的一个很好的工具.