Linux Shell脚本


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系统管理员是航空公司的飞行员,那么使用这个外壳就好比把飞机从自动驾驶中解放出来,并抓住手动控制装置进行更多的机动飞行。

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

像Bash这样的大多数现代shell提供的 构造 允许更复杂的 shell脚本 使常见和复杂任务自动化。

构建体包括 -

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

使用Shell脚本与脚本语言

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

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

shell

Shell允许在Linux操作系统上使用Linux命令,例如 sedgrepteecat 和所有其他基于命令行的实用程序。事实上,几乎所有的命令行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 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脚本在Linux 主机 命令中使用了一个包装器。如果我们想要做更多的事情,并让我们自己的应用程序(如 主机) 在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 进行解析和格式化。最后,使用Web脚本将格式化数据插入到MySQL数据库中。

借助shell的一些理论,让我们开始使用基本构建块,以便在CentOS中自动执行来自Bash shell的任务。

输入输出和重定向

将stdout处理为另一个命令

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

以上,我们已经通过 cat'sstoudwc 一起处理 管道 角色。 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将被视为默认目标 -

  • 标准输入<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 被重定向到将其内容回显到 STDOUTcat 命令。 __

管道字符“|”

管道角色将从第一个命令中获取输出,并将其作为输入传递给下一个命令,从而允许辅助命令对输出执行操作。

现在,让我们将cat的stdout“管”到另一个命令 -

[root@centosLocal centos]# cat output.txt | wc -l
2
[root@centosLocal centos]#

上面, wc 执行从管道传递的 cat的 输出的计算。当从 grepegrep 过滤输出时,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故障排除提示

与专用脚本语言相比,BASH可能有点棘手。BASH脚本中一些最大的挂断是来自错误地转义或不转义传递给shell的脚本操作。如果您几次查看了脚本并且未按预期工作,请不要担心。即使那些每天使用BASH创建复杂脚本的人也很常见。

快速搜索Google或在专家Linux论坛上注册以提出问题将导致快速解决问题。有人很可能有机会碰到确切的问题,并且已经解决了。

BASH脚本是快速创建强大脚本的好方法,从自动管理任务到创建有用的工具。成为专家级的BASH脚本开发人员需要时间和练习。因此,尽可能使用BASH脚本,它是CentOS管理工具箱中的一个很好的工具。