Linux Admin Shell
Bash Shell 简介
就像 GNU Linux 的风格一样,shell 有多种不同的兼容性。 CentOS 中的默认 shell 称为 Bash 或 Bourne Again Shell。 Bash 外壳是由斯蒂芬·伯恩 (Stephen Bourne) 开发的现代修改版 Bourne Shell。 Bash 是由 Ken Thompson 和 Dennis Ritchie 在贝尔实验室开发的 Unix 操作系统上原始 Thompson Shell 的直接替代品(Stephen Bourne 也受雇于贝尔实验室)
每个人都有自己喜欢的外壳,每个人都有自己的长处和难点。但在大多数情况下,Bash 将成为所有 Linux 发行版和最常用的默认 shell。有了经验,每个人都会想探索和使用最适合他们的 shell。但同时,每个人也会想掌握 Bash shell。
其他 Linux shell 包括:Tcsh、Csh、Ksh、Zsh 和 Fish。
开发技能以在专家级别使用任何 Linux shell 对 CentOS 管理员来说极其重要。正如我们之前提到的,与 Windows 不同,Linux 的核心是一个命令行操作系统。 shell 只是一个用户界面,允许管理员(或用户)向操作系统发出命令。如果 Linux 系统管理员是航空公司的飞行员,那么使用 shell 将类似于让飞机脱离自动驾驶并抓住手动控制以实现更机动的飞行。
Linux shell,如 Bash,在计算机科学术语中被称为
命令行解释器。 Microsoft Windows 还有两个命令行解释器,称为 DOS(不要与原始 DOS 操作系统混淆)和 PowerShell。
像 Bash 这样的大多数现代 shell 都提供
结构,允许更复杂的
shell 脚本自动执行常见和复杂的任务。
结构包括-
脚本流控制(ifthen 和 else)
逻辑比较运算(大于、小于、等于)
循环
变量
定义操作的参数(类似于带命令的Switch)
使用 Shell 脚本与脚本语言
在考虑执行任务时,管理员经常问自己:我应该使用 shell 脚本还是脚本语言,如 Perl、Ruby 或 Python?
这里没有固定的规则。 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 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 中也需要花费大量时间。
脚本语言
脚本语言将在外壳之外提供更多控制。上面的 Bash 脚本使用了 Linux
host 命令的包装器。如果我们想做更多事情并让我们自己的应用程序像
host 一样在 shell 之外进行交互怎么办?这是我们将使用脚本语言的地方。
此外,使用高度维护的脚本语言,我们知道我们的操作在大多数情况下可以跨不同系统运行。例如,Python 3.5 可以在安装了相同库的任何其他运行 Python 3.5 的系统上运行。如果我们想在 Linux 和 HP-UX 上运行我们的 BASH 脚本,就不是这样。
有时脚本语言和强大的 shell 之间的界限会变得模糊。可以使用 Python、Perl 或 Ruby 自动执行 CentOS Linux 管理任务。这样做真的很平常。此外,富裕的 shell 脚本开发人员在 Bash 中制作了一个简单但功能强大的网络服务器守护程序。
拥有脚本语言和 shell 自动化任务的经验,CentOS 管理员将能够在需要解决问题时快速确定从哪里开始。使用 shell 脚本启动项目是很常见的。然后随着项目变得更加复杂,逐渐使用脚本(或编译)语言。
此外,可以对项目的不同部分同时使用脚本语言和 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 的行数打印到终端。将
pipe 字符视为传递来自一个命令的输出的"管道",由下一个命令处理。
以下是处理命令重定向时要记住的关键概念-
数量 |
文件描述符 |
人物 |
0 |
标准输入 |
|
1 |
标准输出 |
> |
2 |
标准误差 |
|
|
附加标准输出 |
>> |
|
分配重定向 |
& |
|
管道标准输出到标准输入 |
| |
我们在第一章中介绍了这一点,并没有真正谈论重定向或分配重定向。在 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 的示例-
标准输出
[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 的标准输出"管道"到另一个命令-
[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]#
在上面的命令中,我们从一个包含 65535 的所有数字的文本文件中将每 4 位数字传递给
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 管理工具箱中的绝佳工具。