第二章:从一个Sha-Bang(#!)开始
作者:互联网
在最简单的情况下,脚本程序不过是存储在一个文件里的系统命令列表。这至少让你执行它 时不必重新按顺序键入相同功能的命令序列。
例子 2-1. cleanup: 一个清空/var/log目录下的日志文件的脚本
|
这没有什么不同寻常的,它不过是一组可以容易地从控制台或xterm(译者注:一种图形虚拟控制台). )中顺序键入的命令集。用一种脚本代替这组命令的用处是使你不必每次执行相同任务时都重复地顺序键入它们。脚本变成了一个工具, 并且它也很容易地在一个实际项目被修改或者定制。
例子 2-2. cleanup: 一个改进版的cleanup脚本
|
现在它看起来像一个真正的脚本了。但下面我们将做的更好…
例子 2-3. cleanup: 一个上面脚本的增强版,但不能处理错误
|
因为你可能并不希望把整个系统日志都清空,所以这个版本的cleanup保留了日志中最后的几行日志记录。如果你继续努力地学下去,将会发现更多精练的写法来代替上面的代码。
在脚本开头的 sha-bang ( #!) 是告诉系统这个文件是由特定命令解释器解释的一组命令。 那个 #! 实际上是两个字节的 [1] 魔数, 魔数是指定文件类型的特殊记号,在此是表示这是一个可执行的shell脚本(键入 man magic可了解更多的信息)。紧跟着#!的是一个路径名.这个路径名是解释这个脚本内命令的命令解释器程序的路径:可能是一个shell,也可能是一个编程语言或者是一个软件包程序。这个命令解释器能执行脚本内的命令语句。它从脚本开头(即从#!所在行的下一行)起执行,但是忽略注释行。 [2]
|
上面每一个脚本头行都是不同的命令解释器,如果第一行是/bin/sh, 那就是默认的Shell(Linux系统中bash是默认的shell),否则的话就是其他的解释器. [3] 如果使用#!/bin/sh/bin/sh(因为大多不同的商业UNIX都使用Bourne shell为默认shell)可以使脚本能够移植到非Linux的机器上,虽然这样做你将不能使用Bash许多特有的属性。但这样做的脚本遵循 POSIX [4] sh标准.
值得注意的是,在"#!"后面提供的路径必须是正确的,否则你运行脚本只会收到通常像"Command not found"那样的错误信息。
如果脚本程序只是由一组普通的系统命令而没有使用Shell内置命令的话#!将被忽略。上面的第二个例子被要求以#!,开头是因为变量赋值(lines=50),这就使用了Shell的特有的语句。再次提醒使用#!/bin/sh将调用默认的命令解释器,这在Linux系统上是/bin/bash.
这份指南鼓励使用模块化的方法来写脚本。留意记录像“模板”的代码片断以备将来的脚本使用。最后你能生成一个很好的可扩展的例程库。下面的代码片断可以测试脚本是否被正确的数目参数调用。
很多时候,你会写一个执行实际功能的脚本。本章的第一个脚本就是一个例子。以后它可能会使你记起把这个脚本扩展以完成类似的任务。使用变量代替固定的字符串常量是好的办法,像这样的办法还有用函数代替反复使用的代码块。 |
2.1. 运行脚本
写完一个脚本,你能够运行它用命令:sh scriptname, [5] 另外也也可以用bash scriptname. 来执行(不推荐使用:sh <scriptname, 因为这样会禁止脚本从标准输入里读数据)。更为方便的是你可以使用chmod命令来使脚本自身变为可执行的.
- 你可以:
-
chmod 555 scriptname (使每个人都有读和执行的权限) [6]
- 也可以:
-
chmod +rx scriptname (使每个人都有读和执行的权限)
chmod u+rx scriptname (仅仅使脚本文件拥有者有读和执行的权限)
在给脚本加上执行权限之后,你可以很容易地使用./scriptname. [7] 来执行它。如果脚本以"#!"行开头,将会调用正确的命令解释器来执行它.
最后,把脚本测试并调试完后,如果想把脚本给系统中所有其他的用户使用,你应该把脚本移到目录/usr/local/bin 中(当然,这必须要有root的权限),这样只需简单地在命令行输入scriptname [回车]就能执行脚本了。
注释:
[1] |
一些令人喜爱的UNIX系统(它们都基于4.2BSD)的脚本是四个字节的魔数,在字符”!”后面要求一个空格 -- #! /bin/sh. |
|
[2] |
The #!行将会命令解释器(sh或是bash)在Shell脚本中最先看到的。因为这行以#字符开头,命令解释器最终执行脚本时将会正确的把这一行当做注释行来对待。这行刚刚好只起到了它调用命令解释器的作用。 事实上,如果脚本包含了额外的#!行,bash将会把它当作一个注释.
|
|
[3] |
利用上面所述的特性能找到一些有趣的窍门.
也可以写一个以#!/bin/more,开头的文件,并执行它。执行结果会发现这是一个自我显示的文件。 (一个使用cat命令的here document 能更好地办到这一点--参考例子 17-3). |
|
[4] |
可移植操作系统接口(Portable Operating System Interface),它尝试使类UNIX的操作系统标准化。POSIX的规范可以在站点Open Group site找到. |
|
[5] |
注意:以sh scriptname运行一个Bash脚本将会禁止所有Bash的扩展特性。因此脚本可以会因此而运行失败。 |
|
[6] |
因为运行一个脚本文件需要Shell能读此文件中的命令,因此不仅需要文件的执行权限,也需要文件有读的权限。 |
|
[7] |
为什么不直接用简单地键入scriptname来运行脚本? 如果当前目录(由变量$PWD)的值保存[译者注:也可由命令pwd打印当前目录路径])就是scriptname 脚本文件所在的目录,为什么直接键入scriptname不能运行脚本? 这样运行脚本可能失败。因为由于安全的因素[译者注:如果你感兴趣的话,其中一个安全漏洞可在LinuxSir的Shell版中我发的一篇帖子里找到]当前目录默认不加入到用户的$PATH.变量中。因此你必须明确地指定调用脚本的路径在当前路径:./scriptname. |
标签:脚本,bin,命令,scriptname,echo,Sha,Bang,sh,第二章 来源: https://www.cnblogs.com/simplerude/p/16337866.html