红联Linux门户
Linux帮助

使用 Shell 一些诀窍

发布时间:2011-03-09 21:04:30来源:红联作者:wst021
[align=center]使用 Shell 一些诀窍[/align]


尝试在使用 echo 输出短消息时加引号:

$ echo "Hello, world"
Hello, world


Shell 引用(无论在命令行还是在脚本中加注)是一种将字符串传递给 Shell 的方法,可以避免对字符串中可能包含的任何特殊元字符产生混淆。当字符串包含一个以上的单词或者段落包含空格字符时使用引用。如果单个字符恰好是 Shell 元字符,并且您想去除它的特殊含义,就可以在两边加上引号,例如,当您要传递一个美元符号 ($) 作为字面上的美元符号字符而不是作为变量名前的特殊元字符时。

在引用的文本内部发生各种扩展。例如,在双引号括起来的文本中,变量被展开为它们的值,而单引号括起来的文本内部引用的变量名则不展开。

有三种重要的引用类型需要了解:

1.

通过在前面加反斜杠 (\) 引用单个字符。这样只会传替字符的字面含义,而非它可能包含的任何特殊含义,比如空格符或 Shell 元字符。例如,使用 \* 引用一个星号 (*),它是 Shell 元字符。要引用真正的反斜杠字符,可以使用 \\。
2.

通过在文本字符串两边加双引号 (") 来传递扩展的引用。美元符号 ($) 和单引号 (') 字符会保留其自身含义。因此,和其他字符一起在引用中出现的任何变量名都会被它们的值所替代。新行或特定字符 ($`"\) 前的反斜杠被移除,但是引用的字符会被传递。
3.

使用单引号 (') 将文本括起来以传递文本字符串的字面引用,所有的变量名、元字符等都作为文字字符,而不它们的含义或值来传递。

请注意在不同的 Shell 中引用的确切规则会有所区别。参考您所使用的特殊 Shell 的 man 页面来了解准确规则。

分配一个变量,然后尝试使用各种引用格式输出该变量,如清单 1 中所示。

清单 1. 使用 echo 演示 Shell 变量引用格式


$ myvar = "Hello, world"
$ echo $myvar
Hello, world
$ echo "$myvar"
Hello, world
$ echo '$myvar'
$myvar
$ echo \$myvar
$myvar
$ echo \'$myvar\'
'Hello, world'
$ echo "'$myvar'"
'Hello, world'
$ echo '"$myvar"'
"$myvar"
$ echo \"$myvar\"
"Hello, world"


注意解释变量的方式取决于所使用的引用格式。

注释

在 Shell 中,以井号 (#) 开始一个注释行。井号及其后面跟随的同一行的所有内容都被忽略。尝试输入几行夹杂注释的文本,如清单 2 中所示:

清单 2. 在 Shell 中使用注释


$ # a comment does nothing
$ echo "Hello, world" # This text is ignored
Hello, world
$ echo # This will not output

$ echo 'But a hash (#) can be quoted'
But a hash (#) can be quoted
$ echo "# Even in double quotes"
# Even in double quotes
$


创建 Shell 脚本

正如您所看到的,您可以直接在命令行测试这些 Shell 编程结构。但是,当您完成了单行命令的学习并且真正开始构建更长的程序时,您需要将程序写入称为脚本的文件。脚本 是一个设置了可执行位的文本文件,并且包含由 Shell 语言命令组成的程序。UNIX Shell 是一种解释性语言,这意味着它的程序不经过编译,而是由解释器读取,解释器本身是 Shell 可执行程序,比如 /bin/sh、/bin/bsh 或 /bin/bash。

Shell 脚本的第一行通常都是相同的:

#!/bin/sh


这是 Shell 自己使用的一种特殊注释,用于确定文件的语言或目录。感叹号在 UNIX 和排版术语中常常被称为 bang,后面跟随的路径名告诉 Shell 应该使用来执行该文件的解释器。在本例中是 /bin/sh,它在许多系统中代表 Bourne Shell 可执行程序本身。举例来说,特别为 Korn Shell 编写的脚本应该以 #!/usr/bin/ksh 开始,正如 Ruby 脚本将以 #!/usr/bin/ruby 开始。安装 bash 之后,/bin/sh 通常是到 bash 二进制程序的符号链接。并且考虑到兼容性,使用 /bin/sh 比使用 /bin/bash 更可取。在一些系统中,比如 IBM AIX 5L™,Bourne Shell 可执行程序的名称是 bsh,并且位于 /usr/bin/bsh。

清单 3 提供了 Shell 脚本的简短示例。

清单 3. Shell 脚本示例


#!/bin/sh
# This is a shell script
message = "Hello, world!"
echo "The message is '"$message"'"


按照本系列教程前面文章中的说明,使用 vi 编辑器键入该脚本并保存到名为 myscript 的文件中(请参见参考资料部分)。然后使用 chmod 设置该文件的执行权限,使该文件可以执行:

$ chmod u+x myscript



此命令使该文件只能由您执行。如果希望系统中的所有用户都能执行该文件,那么您还可以为所有用户设置执行权限:

$ chmod a+x myscript



现在您可以运行该脚本。给出该文件的名称和相对于当前工作目录的路径,在路径中使用一个点字符 (.) 来表示:

$ ./myscript
The message is 'Hello, world!'
$


Shell 变量 PATH 包含一组以冒号分隔的目录。它就是您的路径,Shell 总是会“看到”这些目录中的所有文件。UNIX Path 的目的是为了便于运行二进制文件。这就是为什么您只需要键入命令的基本文件名,比如 ls 和 echo,而不用提供它们的完整或相对路径名。如果您将脚本移动到 Path 中的目录,那么只需键入它的名字就可以运行。具体的 Path 取决于您的 UNIX 实现和本地设置,但 Path 中的目录通常包括 /bin、/usr/bin 和 /usr/local/bin。

一些用户对它们的 Shell 进行配置,从而使 PATH 变量包括当前的工作目录,这在 Path 中以点字符 (".") 表示。如此一来,要在当前目录下运行脚本,只需要键入它的名称,不需要指出相对目录。,Shell 按给定的顺序搜索 Path中的目录,从而避免中木马或发生异常情况,一种极其不明智的做法是把当前工作目录放在 Path 的末尾。

要查看您的 Path,可以使用 echo 显示 PATH 变量的内容,如清单 4 所示。

清单 4. 更改 PATH


$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11
$ myscript
myscript: command not found
$ PATH = $PATH":."
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:.
$ myscript
The message is 'Hello, world!'
$


在解释器名称的后面可以附加特殊选项或标志,比如 /usr/bin/bsh -n,这用于调试目的。连字符关闭选项,加号则打开选项。特殊的内置环境变量 -(一个连字符)包含当前 Shell 的完整选项列表。

尝试在您当前的交互式 Shell 中设置了哪些选项。通过使用 echo 显示 - 变量的内容来完成这项任务:

$ echo $-
himBH
$


参考您使用的 Shell 的 man 页面来获取当前的标志和选项列表。表 1 提供了 AIX® 上的 Bourne Shell 的常用标志列表,以及对每种标志作用的简要说明。

表 1. AIX Bourne Shell 的常用选项
标志 描述
-a 导出所有已分配值的变量。
-c Variable 执行从变量 中读取的命令。
-e 当命令满足以下条件之一时立即退出:命令退出时返回比 0 大的值;命令不是 while、until 或 if 结构的一部分;命令不经过 AND 或 OR 检测;或者命令不是管道前加感叹号。
-f 禁用所有文件名替

换。
-h 定义函数时,定位和记住函数内部调用的所有命令。
-i 指定交互式 Shell。
-k 将所有关键字 都放入命令的环境。
-n 读取命令,但是不执行它们。
-r 调用受限制的 Shell。
-s 从标准输入读取命令,然后将输出写入标准错误(不包括 Shell 内置命令的输出)。
-t 读取并执行单个命令,然后退出。
-u 在脚本中,将所有未定义 变量视为错误。当尝试变量替换时退出。
-v 当读取输入行时将其显示出来。
-x 在执行命令之前显示其完整命令(包括所有的参数和选项)。
文章评论

共有 58 条评论

  1. 木子leal 于 2011-08-15 09:25:20发表:

    收藏一下~

  2. every_why 于 2011-08-15 07:24:05发表:

    好贴,支持

  3. tan0620 于 2011-08-11 15:47:05发表:

    感谢分享

  4. tuerqi8 于 2011-08-10 18:07:08发表:

    回去练习下,谢谢楼主教导

  5. yrj8008037241 于 2011-07-12 13:42:50发表:

    :0wmjh(1

  6. 天真花语 于 2011-07-08 11:50:06发表:

    学习、、、、中

  7. daen 于 2011-06-27 18:59:54发表:

    学习中...

  8. hong.lanxu 于 2011-05-06 16:18:34发表:

    不错,实在不错。

  9. 啄木鸟001 于 2011-05-04 23:32:54发表:

    哇,学习了~~

  10. tcsun 于 2011-03-28 20:06:44发表:

    留下学习

  11. hb_5015 于 2011-03-19 13:58:35发表:

    这个逻辑性比较强~

  12. hibluebbs 于 2011-03-13 20:59:14发表:

    1# wst021

    $ echo $-
    himBH
    $
    什么意思?

  13. lp518 于 2011-03-12 18:21:17发表:

    学习了~

  14. 619509429 于 2011-03-10 13:05:03发表:

    受教了!

  15. laoshue 于 2011-03-10 09:00:06发表:

    坐个位置学习

  16. tiany524 于 2011-03-09 23:28:58发表:

    好 学习了

  17. pallana 于 2011-03-09 22:42:00发表:

    学习了

  18. coov 于 2011-03-09 21:36:52发表:

    有点难度噢