📅  最后修改于: 2020-10-31 13:40:22             🧑  作者: Mango
就像GNU Linux的风格一样,shell种类很多,兼容性也各不相同。 CentOS中的默认外壳称为Bash或Bourne Again Shell。 Bash shell是由Stephen Bourne开发的Bourne Shell的现代版本。 Bash是Ken Thompson和Dennis Ritchie在Bell Labs开发的Unix操作系统上原始Thompson Shell的直接替代品(Stephen Bourne也受雇于Bell Labs)
每个人都有自己喜欢的外壳,每个人都有其长处和难处。但是在大多数情况下,Bash将成为所有Linux发行版中的默认外壳,并且是最常用的外壳。有了经验,每个人都会想探索和使用最适合他们的外壳。但是,与此同时,每个人也都希望掌握Bash shell。
其他Linux外壳包括:Tcsh,Csh,Ksh,Zsh和Fish。
对于CentOS管理员来说,开发技能以使用专家级水平的任何Linux Shell极为重要。如前所述,与Windows不同,Linux的核心是命令行操作系统。 Shell只是用户界面,允许管理员(或用户)向操作系统发出命令。如果Linux系统管理员是航空公司的飞行员,则使用外壳类似于将飞机从自动驾驶仪上取下,然后抓住手动控制装置来进行更灵活的飞行。
Linux外壳(如Bash)用计算机科学术语称为“命令行解释器” 。 Microsoft Windows还具有两个称为DOS(不要与原始DOS操作系统混淆)的命令行解释器。
像Bash这样的大多数现代shell提供了允许更复杂的shell脚本自动执行常见任务和复杂任务的构造。
构造包括-
管理员经常在考虑执行任务时问自己:我应该使用Shell脚本还是脚本语言(例如Perl,Ruby或Python)?
这里没有固定的规则。 Shell与脚本语言之间只有典型的区别。
Shell允许在Linux操作系统上使用Linux命令,例如sed , grep , tee , cat和所有其他基于命令行的实用程序。实际上,几乎所有命令行Linux实用程序都可以在您的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 dns
dns.google.com has address 172.217.6.46
-doing www
www.google.com has address 172.217.6.36
-doing test
-doing dev
-doing mail
googlemail.l.google.com has address 172.217.6.37
-doing rdp
-doing remote
[rdc@centos ~]$
利用我们外壳中的简单Linux命令,我们能够制作一个简单的5行脚本来审核单词列表中的DNS名称。即使使用完善的DNS库,在Perl, Python或Ruby中也将花费大量时间。
脚本语言将在Shell之外提供更多控制。上面的Bash脚本在Linux主机命令周围使用了包装器。如果我们想做更多的事情并使自己的应用程序(例如主机)在外壳外进行交互,该怎么办?这是我们使用脚本语言的地方。
同样,通过高度维护的脚本语言,我们知道我们的动作将在大多数情况下在不同系统上工作。 Python的3.5,例如,将工作运行的Python 3.5安装在同一个库中的任何其他系统。如果要在Linux和HP-UX上运行BASH脚本,则不是这样。
有时,脚本语言和强大的shell之间的界限可能会模糊。可以使用Python,Perl或Ruby自动执行CentOS Linux管理任务。这样做确实很平常。同样,富裕的shell脚本开发人员在Bash中创建了一个简单但功能正常的Web服务器守护程序。
凭借在脚本语言和Shell中自动执行任务方面的经验,CentOS管理员将能够快速确定需要解决问题时从何处开始。使用Shell脚本启动项目是很常见的。然后随着项目变得越来越复杂,发展为脚本(或编译)语言。
同样,可以将脚本语言和外壳程序脚本用于项目的不同部分。一个示例可能是Perl脚本,用于抓取网站。然后,使用Shell脚本使用sed , awk和egrep进行解析和格式化。最后,使用PHP脚本通过Web GUI将格式化的数据插入MySQL数据库。
在shell背后有了一些理论,让我们开始使用基本的构建块来自动执行CentOS中Bash shell的任务。
处理标准输出到另一个命令-
[rdc@centos ~]$ cat ~/output.txt | wc -l
6039
[rdc@centos ~]$
上面,我们已将cat’sstoud传递给wc ,以使用竖线字符进行处理。然后, wc处理了cat的输出,将output.txt的行数打印到终端。将管道字符视为传递一个命令的输出的“管道”,并由下一个命令处理。
以下是在处理命令重定向时要记住的关键概念-
Number | File descriptor | Character |
---|---|---|
0 | standard input | < |
1 | standard output | > |
2 | standard error | |
append stdout | >> | |
assign redirection | & | |
pipe stdout into stdin | | |
我们在第一章中介绍了这一点,而没有真正谈论重定向或分配重定向。在Linux中打开终端时,您的shell被视为默认目标-
让我们看看这是如何工作的-
[rdc@centos ~]$ lsof -ap $BASHPID -d 0,1,2
COMMAND PID USER **FD** TYPE DEVICE 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的示例-
[root@centosLocal centos]# echo "I am coming from Standard output or STDOUT." >
output.txt && cat output.txt
I am coming from Standard output or STDOUT.
[root@centosLocal centos]#
也可以将stdout和stderr都发送到单独的文件-
bash-3.2# find / -name passwd 1> good.txt 2> err.txt
bash-3.2# cat good.txt
/etc/pam.d/passwd
/etc/passwd
bash-3.2# cat err.txt
find: /dev/fd/3: Not a directory
find: /dev/fd/4: Not a directory
bash-3.2#
搜索整个文件系统时,遇到两个错误。每个都发送到一个单独的文件中,以供日后阅读,而返回的结果将放入一个单独的文本文件中。
当执行将大量数据输出到终端(例如编译应用程序)的操作时,将stderr发送到文本文件可能会很有用。这将允许细读可能从终端回滚历史记录中丢失的错误。
将STDOUT传递到文本文件时的一个注意事项是>>和>之间的区别。双“ >>”将追加到文件中,而单数形式将破坏文件并写入新内容(因此所有先前的数据都将丢失)。
[root@centosLocal centos]# cat < stdin.txt
Hello,
I am being read form Standard input, STDIN.
[root@centosLocal centos]#
在上面的命令中,文本文件stdin.txt被重定向到cat命令,该命令将其内容回显到STDOUT 。
管道字符将从第一个命令中获取输出,并将其作为输入传递到下一个命令中,从而允许辅助命令对输出执行操作。
现在,让我们将cat的stdout“传送”到另一个命令-
[root@centosLocal centos]# cat output.txt | wc -l
2
[root@centosLocal centos]#
上面, wc对从管道传递过来的cat的输出执行计算。当过滤来自grep或egrep的输出时,pipe命令特别有用-
[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可能会有些棘手。 BASH脚本中最大的挂断是由于错误地转义或不转义脚本操作而导致的。如果您看过几次脚本,但未按预期工作,请不要担心。即使对于那些每天使用BASH创建复杂脚本的人来说,这也是很常见的。
快速搜索Google或在Linux专家论坛上注册以提出问题,将快速解决问题。有人很可能会遇到确切的问题,并且已经解决。
BASH脚本是一种快速创建功能强大的脚本的好方法,可用于从自动化管理任务到创建有用工具的所有操作。成为专家级的BASH脚本开发人员需要花费时间和实践。因此,请尽可能使用BASH脚本,它是CentOS管理工具箱中的一个很好的工具。