Linux管理员 - Shell脚本



Bash Shell简介

像GNU Linux的不同版本一样,Shell也有很多种类,并且兼容性各不相同。CentOS中的默认Shell称为Bash或Bourne Again Shell。Bash Shell是Stephen Bourne开发的Bourne Shell的现代化修改版本。Bash是Bell Labs的Ken Thompson和Dennis Ritchie在Unix操作系统上开发的原始Thompson Shell的直接替代品(Stephen Bourne也受雇于Bell Labs)

每个人都有自己喜欢的Shell,每个Shell都有其优势和劣势。但总的来说,Bash将成为所有Linux发行版中的默认Shell,并且是最常用的。随着经验的积累,每个人都会希望探索和使用最适合自己的Shell。但同时,每个人也希望掌握Bash Shell。

其他Linux Shell包括:Tcsh、Csh、Ksh、Zsh和Fish。

培养使用任何Linux Shell达到专家级别的技能对于CentOS管理员来说极其重要。正如我们之前提到的,与Windows不同,Linux的核心是一个命令行操作系统。Shell只是一个用户界面,允许管理员(或用户)向操作系统发出命令。如果Linux系统管理员是一位航空公司飞行员,那么使用Shell就像将飞机从自动驾驶仪上移开,并抓住手动控制杆以进行更灵活的飞行。

像Bash这样的Linux Shell在计算机科学术语中被称为命令行解释器。Microsoft Windows也有两个命令行解释器,称为DOS(不要与原始DOS操作系统混淆)和PowerShell。

大多数现代Shell(如Bash)提供结构,允许更复杂的Shell脚本自动化常见和复杂的任务。

结构包括 -

  • 脚本流程控制(ifthen和else)
  • 逻辑比较运算(大于、小于、等于)
  • 循环
  • 变量
  • 定义操作的参数(类似于命令的开关)

使用Shell脚本与脚本语言

在考虑执行任务时,管理员常常会问自己:我应该使用Shell脚本还是使用Perl、Ruby或Python等脚本语言?

这里没有固定的规则。Shell与脚本语言之间只有典型的区别。

Shell

Shell允许使用Linux命令,如sedgrepteecat以及Linux操作系统上的所有其他基于命令行的实用程序。事实上,几乎所有命令行Linux实用程序都可以在您的Shell中编写脚本。

使用Shell的一个很好的例子是快速检查主机列表以进行DNS解析的脚本。

我们用于检查DNS名称的简单Bash脚本 -

#!/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 ~]$

利用我们Shell中的简单Linux命令,我们能够制作一个简单的5行脚本,用于从词表中审核DNS名称。即使使用良好实现的DNS库,这在Perl、Python或Ruby中也需要花费相当长的时间。

脚本语言

脚本语言将提供Shell之外的更多控制。上面的Bash脚本使用了Linuxhost命令的包装器。如果我们想做更多的事情,并制作我们自己的类似于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脚本使用sedawkegrep进行解析和格式化。最后,使用PHP脚本通过Web GUI将格式化数据插入MySQL数据库。

在了解了一些Shell的理论知识后,让我们开始学习从CentOS中的Bash Shell自动化任务的基本构建块。

输入输出和重定向

将stdout处理到另一个命令 -

[rdc@centos ~]$ cat ~/output.txt | wc -l 
6039 
[rdc@centos ~]$

上面,我们使用pipe字符将catstdout传递给wc进行处理。然后,wc处理来自cat的输出,将output.txt的行数打印到终端。将pipe字符视为一个“管道”,将一个命令的输出传递给另一个命令进行处理。

以下是处理命令重定向时需要记住的关键概念 -

编号 文件描述符 字符
0 标准输入 <
1 标准输出 >
2 标准错误
追加stdout >>
分配重定向 &
将stdout管道到stdin |

我们在第一章中介绍了这一点,但并没有真正谈论重定向或分配重定向。在Linux中打开终端时,您的Shell被视为以下内容的默认目标 -

  • 标准输入 < 0
  • 标准输出 > 1
  • 标准错误 2

让我们看看它是如何工作的 -

[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的示例 -

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]#

也可以将stdoutstderr都发送到不同的文件 -

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传递到文本文件时需要注意的一点是>>>之间的区别。双“>>”将追加到文件,而单数形式将覆盖文件并写入新内容(因此所有先前的数据都将丢失)。

STDIN

[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的输出执行计算,该输出是从管道传递的。管道命令在过滤grepegrep的输出时特别有用 -

[root@centosLocal centos]# egrep "^[0-9]{4}$" /usr/dicts/nums | wc -l  
9000 
[root@centosLocal centos]#

在上面的命令中,我们将每个4位数字从包含从65535传递的所有数字的文本文件中传递给wc,并通过egrep过滤器。

使用&重定向输出

可以使用&字符重定向输出。如果我们想将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管理工具箱中的一款很棒的工具。

linux_admin_shell_scripting.htm
广告