[一] 编写第一个 Shell 脚本

什么是 Shell 脚本?

最简单的解释,一个 shell 脚本就是一个包含一系列命令的文件。shell 读取这个文件,然后执行 文件中的所有命令,就好像这些命令已经直接被输入到了命令行中一样。

Shell 有些独特,因为它不仅是一个功能强大的命令行接口,也是一个脚本语言解释器。我们将会看到, 大多数能够在命令行中完成的任务也能够用脚本来实现,同样地,大多数能用脚本实现的操作也能够 在命令行中完成。

虽然我们已经介绍了许多 shell 功能,但只是集中于那些经常直接在命令行中使用的功能。 Shell 也提供了一些通常(但不总是)在编写程序时才使用的功能。

怎样编写一个 Shell 脚本

为了成功地创建和运行一个 shell 脚本,我们需要做三件事情:

  1. 编写一个脚本。 Shell 脚本就是普通的文本文件。所以我们需要一个文本编辑器来书写它们。最好的文本 编辑器都会支持语法高亮,这样我们就能够看到一个脚本关键字的彩色编码视图。语法高亮会帮助我们查看某种常见 错误。为了编写脚本文件,vim,gedit,kate,和许多其它编辑器都是不错的候选者。
  2. 使脚本文件可执行。 系统会相当挑剔不允许任何旧的文本文件被看作是一个程序,并且有充分的理由! 所以我们需要设置脚本文件的权限来允许其可执行。
  3. 把脚本放置到 shell 能够找到的地方 当没有指定可执行文件明确的路径名时,shell 会自动地搜索某些目录, 来查找此可执行文件。为了最大程度的方便,我们会把脚本放到这些目录当中。

脚本文件格式

为了保持编程传统,我们将创建一个 “hello world” 程序来说明一个极端简单的脚本。所以让我们启动 我们的文本编辑器,然后输入以下脚本:

#!/bin/bash
# This is our first script.
echo ‘Hello World!‘

对于脚本中的最后一行,我们应该是相当的熟悉,仅仅是一个带有一个字符串参数的 echo 命令。 对于第二行也很熟悉。它看起来像一个注释,我们已经在许多我们检查和编辑过的配置文件中 看到过。关于 shell 脚本中的注释,它们也可以出现在文本行的末尾,像这样:

echo ‘Hello World!‘ # This is a comment too

文本行中,# 符号之后的所有字符都会被忽略。

类似于许多命令,这也在命令行中起作用:

[[email protected] ~]$ echo ‘Hello World!‘ # This is a comment too
Hello World!

虽然很少在命令行中使用注释,但它们也能起作用。

我们脚本中的第一行文本有点儿神秘。它看起来它应该是一条注释,因为它起始于一个#符号,但是 它看起来太有意义,以至于不仅仅是注释。事实上,这个#!字符序列是一种特殊的结构叫做 shebang。 这个 shebang 被用来告诉操作系统将执行此脚本所用的解释器的名字。每个 shell 脚本都应该把这一文本行 作为它的第一行。

让我们把此脚本文件保存为 hello_world。

可执行权限

下一步我们要做的事情是让我们的脚本可执行。使用 chmod 命令,这很容易做到:

[[email protected]~]$ ls -l hello_world
-rw-r--r-- 1  vforbox    vforbox      63  2016-02-28 10:10 hello_world
[[email protected]~]$ chmod 755 hello_world
[[email protected]~]$ ls -l hello_world
-rwxr-xr-x 1  vforbox   vfobox      63  2016-02-28 10:10 hello_world

对于脚本文件,有两个常见的权限设置;权限为755的脚本,则每个人都能执行,和权限为700的 脚本,只有文件所有者能够执行。注意为了能够执行脚本,脚本必须是可读的。

脚本文件位置

当设置了脚本权限之后,我们就能执行我们的脚本了:

[[email protected]~]$ ./hello_world  Hello World! 

为了能够运行此脚本,我们必须指定脚本文件明确的路径。如果我们没有那样做,我们会得到这样的提示:

[[email protected]~]$ hello_world
bash: hello_world: command not found

为什么会这样呢?什么使我们的脚本不同于其它的程序?结果证明,什么也没有。我们的 脚本没有问题。是脚本存储位置的问题。 PATH 环境变量及其它在系统 查找可执行程序方面的作用。如果没有给出可执行程序的明确路径名,那么系统每次都会 搜索一系列的目录,来查找此可执行程序。这个/bin 目录就是其中一个系统会自动搜索的目录。 这个目录列表被存储在一个名为 PATH 的环境变量中。这个 PATH 变量包含一个由冒号分隔开的目录列表。 我们可以查看 PATH 的内容:

[[email protected]~]$ echo $PATH
/home/vforbox/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:

这里我们看到了我们的目录列表。如果我们的脚本驻扎在此列表中任意目录下,那么我们的问题将 会被解决。注意列表中的第一个目录,/home/vforbox/bin。大多数的 Linux 发行版会配置 PATH 变量,让其包含 一个位于用户家目录下的 bin 目录,从而允许用户能够执行他们自己的程序。所以如果我们创建了 一个 bin 目录,并把我们的脚本放在这个目录下,那么这个脚本就应该像其它程序一样开始工作了:

[[email protected]~]$ mkdir bin
[[email protected]~]$ mv hello_world bin
[[email protected]~]$ hello_world
Hello World!

它的确工作了。

如果这个 PATH 变量不包含这个目录,我们能够轻松地添加它,通过在我们的.bashrc 文件中包含下面 这一行文本:

export PATH=~/bin:"$PATH"

当做了这个修改之后,它会在每个新的终端会话中生效。为了把这个修改应用到当前的终端会话中, 我们必须让 shell 重新读取这个 .bashrc 文件。这可以通过 “sourcing”.bashrc 文件来完成:

[[email protected]~]$ . .bashrc

这个点(.)命令是 source 命令的同义词,一个 shell 内部命令,用来读取一个指定的 shell 命令文件, 并把它看作是从键盘中输入的一样。



注意:在 Ubuntu 系统中,如果存在 ~/bin 目录,当执行用户的 .bashrc 文件时, Ubuntu 会自动地添加这个 ~/bin 目录到 PATH 变量中。所以在 Ubuntu 系统中,如果我们创建 了这个 ~/bin 目录,随后退出,然后再登录,一切会正常运行。


脚本文件的好去处

这个 ~/bin 目录是存放为个人所用脚本的好地方。如果我们编写了一个脚本,系统中的每个用户都可以使用它, 那么这个脚本的传统位置是 /usr/local/bin。系统管理员使用的脚本经常放到 /usr/local/sbin 目录下。 大多数情况下,本地支持的软件,不管是脚本还是编译过的程序,都应该放到 /usr/local 目录下, 而不是在 /bin 或 /usr/bin 目录下。这些目录都是由 Linux 文件系统层次结构标准指定,只包含由 Linux 发行商 所提供和维护的文件。

更多的格式技巧

严肃认真的脚本书写,一个关键目标是为了维护方便;也就是说,一个脚本可以轻松地被作者或其它 用户修改,使它适应变化的需求。使脚本容易阅读和理解是一种方便维护的方法。

缩进和行继续符

当雇佣长命令的时候,通过把命令在几个文本行中展开,可以提高命令的可读性。

[[email protected]~]$ find playground \( -type f -not -perm 0600 -exec chmod 0600 ‘{}’ ‘;’ \) -or \( -type d -not -perm 0711 -exec chmod 0711 ‘{}’ ‘;’ \)

显然,这个命令有点儿难理解,当第一眼看到它的时候。在脚本中,这个命令可能会比较容易 理解,如果这样书写它:

find playground     \(         -type f         -not -perm 0600         -exec chmod 0600 ‘{}’ ‘;’     \)     -or     \(         -type d         -not -perm 0711         -exec chmod 0711 ‘{}’ ‘;’     \)

通过使用行继续符(反斜杠-回车符序列)和缩进,这个复杂命令的逻辑性更清楚地描述给读者。 这个技巧在命令行中同样生效,虽然很少使用它,因为输入和编辑这个命令非常麻烦。脚本和 命令行的一个区别是,脚本可能雇佣 tab 字符拉实现缩进,然而命令行却不能,因为 tab 字符被用来 激活自动补全功能。

为书写脚本配置 vim

这个 vim 文本编辑器有许多许多的配置设置。有几个常见的选项能够有助于脚本书写:

:syntax on

打开语法高亮。通过这个设置,当查看脚本的时候,不同的 shell 语法元素会以不同的颜色 显示。这对于识别某些编程错误很有帮助。并且它看起来也很酷。注意为了这个功能起作用,你 必须安装了一个完整的 vim 版本,并且你编辑的文件必须有一个 shebang,来说明这个文件是 一个 shell 脚本。如果对于上面的命令,你遇到了困难,试试 :set syntax=sh。

:set hlsearch

打开这个选项是为了高亮查找结果。比如说我们查找单词“echo”。通过设置这个选项,这个 单词的每个实例会高亮显示。

:set tabstop=4

设置一个 tab 字符所占据的列数。默认是8列。把这个值设置为4(一种常见做法), 从而让长文本行更容易适应屏幕。

:set autoindent

打开 “auto indent” 功能。这导致 vim 能对新的文本行缩进与刚输入的文本行相同的列数。 对于许多编程结构来说,这就加速了输入。停止缩进,输入 Ctrl-d。

通过把这些命令(没有开头的冒号字符)添加到你的 ~/.vimrc 文件中,这些改动会永久生效。

总结归纳

在这脚本编写的第一章中,我们已经看过怎样编写脚本,怎样让它们在我们的系统中轻松地执行。 我们也知道了怎样使用各种格式技巧来提高脚本的可读性(可维护性)。在以后的各章中,轻松维护 会作为编写好脚本的中心法则一次又一次地出现。

时间: 2024-12-20 22:25:10

[一] 编写第一个 Shell 脚本的相关文章

编写简单的Shell脚本

在一些复杂的Linux维护工作中,大量重复性的输入和操作不但费时费力,而且容易出错,而编写一个恰到好处的shell脚本程序,可以批量处理.自动化的完成一系列维护任务,大大减轻了管理员的负担 shell脚本基础 1. 编写第一个shell脚本 Linux中的shell脚本是一个特殊的应用程序,介于操作系统内核和用户之间,充当了一个命令解释器的角色,负责接收用户的操作指令并进行解释,将需要执行的操作传递给内核执行,并输出执行结果 常见的shell解释器 可通过/etc/shells文件了解当前系统所

转:Shell 编程--本文结合大量实例阐述如何编写一个shell脚本

转自:情報官世界 本文结合大量实例阐述如何编写一个shell脚本. 为什么要进行shell编程 在Linux系统中,虽然有各种各样的图形化接口工具,但是sell仍然是一个非常灵活的工具.Shell不仅仅是命令的收集,而且是一门非常棒的编程语言.您可以通过使用shell使大量的任务自动化,shell特别擅长系统管理任务,尤其适合那些易用性.可维护性和便携性比效率更重要的任务. 下面,让我们一起来看看shell是如何工作的: 建立一个脚本 Linux中有好多中不同的shell,但是通常我们使用bas

编写可靠Linux shell脚本的八个建议

这八个建议,来源于键者几年来编写 shell 脚本的一些经验和教训.事实上开始写的时候还不止这几条,后来思索再三,去掉几条无关痛痒的,最后剩下八条.毫不夸张地说,每条都是精挑细选的,虽然有几点算是老生常谈了. 1. 指定bash shell 脚本的第一行,#!之后应该是什么? 如果拿这个问题去问别人,不同的人的回答可能各不相同.我见过www.1.qixoo.com/usr/bin/env bash,也见过/bin/bash,还有/usr/bin/bash,还有/bin/sh,还有/usr/bin

第一个shell脚本——修改配置文件

有需求,可以让自己偷懒才是学习的真正动力.由于测试环境在构建代码之后总是需要手动修改配置文件,因此边学习边完成了一个shell脚本,可以一键修改. 定义了一个函数,输出信息以绿色字体显示. function echo_green { echo -e "\033[32m$1\033[0m" } 输出提示信息 echo_green "是否一键修改xxx?(y/n)" 读取键盘输入 read answer 要修改的配置文件有两类:一类是明确清楚应该修改哪些字符串,直接用替

shell脚本中执行另一个shell脚本

分类: 可以在一个shell脚本中执行另一个shell脚本(或非可执行文件,主要用于取得一些变量的值),方法是: . 文件名(包括路径) 或 变量=文件名(包括路径) . $变量 注意,圆点后面有个空格. 这样,在本shell脚本的后面部分就可以引用其他文件中声明的一些变量. 当再用这些变量去执行第3个脚本时,我不知是怎么回事,总是有些莫名其妙的错误,发现只有这个文件中不存在空行才行,哪怕只有一个注释符,都不会出错,就是不能有空行. 其实我想应该也不是这个问题,而是windows和linux处理

Linux系统的rm命令太危险,一不小心就会删除系统文件。写一个shell脚本来替换系统的rm命令,

Linux系统的rm命令太危险,一不小心就会删除系统文件.写一个shell脚本来替换系统的rm命令,要求当删除一个文件或者目录时都要做一个备份,然后再删除. 假设有一个大的分区/data/,每次删除文件或者目录前,都要在/data/下面创建一个隐藏目录,以日期/时间命名,比如/data/.201802021054,然后把所有删除的文件同步到该目录下面,可以使用rsync -R把文件路径一同同步 答案: #!/bin/bash d=`date +%Y%m%d%H%M` read -p "Are y

每秒执行一个shell脚本)(转)

Linux一个简单的每秒执行命令shell脚本 2012-08-06 11:47:06 分类: Python/Ruby 上周迁移了一台服务器,发现其中一个项目的数据没有更新,查询原服务器的数据,数据有更新,并找到了rsync服务,从其他服务器传输数据,那么如何找到这台服务器?因为是从远程传输到本地,而且不是很频繁,手动查找通信记录,没有结果. 写了一个脚本进行跟踪下,考虑到通信时间短的问题. 需要每秒执行一次命令,通过linux自带的cron却不能实现,新版的cron据说可以精确到秒. 1.编写

小鸟初学Shell编程(二)编写简单的Shell脚本

Shell脚本 编写Python.PHP脚本通常需要掌握语言的函数,那么Shell脚本则不需要,只需要掌握Linux命令就可以编写Shell脚本,因为Shell脚本就是由多个Linux命令组成,通过将多个Linux命令组合保存成一个脚本文件,可直接给其他人使用. 组合命令 进入一个目录,查看目录的文件,这个过程分别需要执行两条命令,分别是cd 和ls. 分开执行两个命令的形式如下: [[email protected] usr]# cd /usr/ [[email protected] usr]

shell基础学习系列一:第一个shell脚本

打开文本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本执行. 输入一些代码: #!/bin/bash echo "Hello World !" “#!” 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell.echo命令用于向窗口输出文本. 运行Shell脚本有两种方法. 作为可执行程序 将上面的代码保存为test.sh,并 cd 到相应目录: chmod +x ./test.sh #使脚本具有执行权限 ./test.sh #执