LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3427|回复: 19

bash -e #exit on all errors如何理解?感谢ti8er解惑

[复制链接]
发表于 2008-10-23 23:09:23 | 显示全部楼层 |阅读模式
我在BLFS6.3手册的xorg7章节看到一个脚本范例
开头就是bash -e #exit on all errors

大概改了改里边的内容执行后迟迟不见结果就结束了...
后来准备下班
logout回车后 之前的脚本忽然开始执行了
--囧我一跳

http://www.linuxfromscratch.org/blfs/view/stable/x/xorg7.html

后来仔细读了下脚本下面的说明有提到exit但是始终不理解
为什么不开头就以#!/bin/bash -e开头呢?
The above shell will exit immediately on error. If it runs to completion, you should manually exit the shell before continuing on to the next set of instructions.
=============================================
详解请看7楼精彩回复
发表于 2008-10-23 23:28:20 | 显示全部楼层
出错就退出。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-10-23 23:33:41 | 显示全部楼层
Post by 晨想;1898394
出错就退出。


为什么没有错误就根本不执行呢?

还是说结尾+ exit就可以 明天试下
回复 支持 反对

使用道具 举报

发表于 2008-10-23 23:35:55 | 显示全部楼层
这里面不好理解的多了, 不抄代码光思考的人们不知道啊,咱这抄代码的问问吧, 呵呵, 弄不好还被楼上的楼上的锁帖子说无聊

我觉得这代码是有问题的, bash -e这一行启动一个新的bash,一开始就就执行完了(实际上没事做),然后等你手动退出,然后再执行下一句,也就是section=proto

因此这段代码正确的做法我觉得应该是先输入bash -e然后回车,这时进行新的shell,然后在这个新的shell里再输入下边那此个命令吧

我是个菜鸟,上边是我猜的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-10-23 23:49:19 | 显示全部楼层
Post by wangjt;1898398
这里面不好理解的多了, 不抄代码光思考的人们不知道啊,咱这抄代码的问问吧, 呵呵, 弄不好还被楼上的楼上的锁帖子说无聊

我觉得这代码是有问题的, bash -e这一行启动一个新的bash,一开始就就执行完了(实际上没事做),然后等你手动退出,然后再执行下一句,也就是section=proto

因此这段代码正确的做法我觉得应该是先输入bash -e然后回车,这时进行新的shell,然后在这个新的shell里再输入下边那此个命令吧

我是个菜鸟,上边是我猜的

我明白了 这个脚本希望我们连续使用
比如
#!/bin/bash
section=proto
version=7.2
mkdir $section
cd $section
<.....此处略去**字>

bash -e #exit on all errors
section=util
version=7.2
mkdir $section
cd $section
<.....此处略去**字>

bash -e #exit on all errors
section=lib
version=7.2
mkdir $section
cd $section
<.....此处略去**字>
.....
因为前后有依赖关系 所以检查下每个阶段是否有错误
而每个阶段都是一个新开的shell
"If it runs to completion, you should manually exit the shell before continuing on to the next set of instructions."
就是让我们手动去exit 然后执行下一组

只是像我这种抄抄者
开头proto就用bash -e #exit on all errors确实有点不妥
谢谢二位
回复 支持 反对

使用道具 举报

发表于 2008-10-25 11:47:59 | 显示全部楼层
Post by wangjt;1898398
这里面不好理解的多了, 不抄代码光思考的人们不知道啊,咱这抄代码的问问吧, 呵呵, 弄不好还被楼上的楼上的锁帖子说无聊

我觉得这代码是有问题的, bash -e这一行启动一个新的bash,一开始就就执行完了(实际上没事做),然后等你手动退出,然后再执行下一句,也就是section=proto

因此这段代码正确的做法我觉得应该是先输入bash -e然后回车,这时进行新的shell,然后在这个新的shell里再输入下边那此个命令吧

我是个菜鸟,上边是我猜的


唉,怎么又是你说代码有问题啊……

没有任何问题!

等下我来解释。
回复 支持 反对

使用道具 举报

发表于 2008-10-25 12:28:30 | 显示全部楼层

bash -e是什么?

bash -e 是什么?

要搞清这个问题,我们先得明白:

bash是什么?

很多人可能会说,bash不就是终端吗?

错!

bash != terminal

想想我们开机进入一个登录界面,输入用户和密码后进入另一个“操作界面”。这两个界面,都运行于terminal之上。而这个terminal,其实是一个tty。一般Linux,都会有6个tty,也就是6个终端,严格地说,叫“虚拟终端”。

终端的第一个界面,为login;第二个界面,称为shell。

bash,就是shell,叫“壳”,或者通俗点,是“命令解释器”。

shell有很多种:sh、bash、ksh、dash、fish等等。基本都是以“sh"结尾,以表明是“shell“。

shell中运行shell
在shell中可以运行各种命令,进行相关操作。其中比较有意思的就是,shell中运行另一个shell会怎么样?

比如在bash下,运行命令sh,会怎么样呢?

其实结果就是在bash之上,打开了sh命令解释器。这时候的运行层次,从低到高就是:

terminal==>bash==>sh

输入exit命令,就会退出shell。
如果在上面的层次中,输入一次exit,就会退出sh,回到bash;再输入一次exit,就退出bash,回到了login。

而login不支持exit这个命令,也就是这时已经无法再退了。

同理,在bash下运行命令bash,将打开另一个bash,只是这两个特征完全相同,我们看不出来而已。

要检验很简单,输入一次exit,如果马上就退出到了login界面,就说明现在只有一个bash;反之,就不只一个。

如果在图形界面下的终端,也可以如此校验,只是最后退出时是关闭了终端窗口,而不是出现login界面而已。

bash -e

这是一个带参数的shell启动命令,这个参数表示,一出错,马上退出bash。

什么叫“出错”?

出错就是stderr,标准错误文件,注意,它是一个文件!

在执行程序的过程中,只要出现了和系统要求的预期不一样时,就会有结果输出到stderr,也就是“出错”了。

好了,那么我们现在来较验一下bash -e的执行情况。

为方便,我们在图形界面下较验:

先打开一个图形终端,然后输入

exit

这时你会发现终端关闭了,说明这时候只有一个shell级别。

再次打开,先输入

bash

然后再输入

exit

你会发现图形终端没有关闭,因为我们又打开了一个bash,只是两个bash完全一样,我们看不出来而已。

再来一次

exit

你发现图形终端关闭了,也就是退出了第一个shell。

     开始校验bash -e
这次输入

bash -e

上面提到,这个参数的意思是,一旦出错,就退出当前的shell。那么我们来“人为制造”一个错误看看:

输入命令

ld

这时会提示错误:ld后面没有输入文件。

那么,现在bash退出了吗?如何校验?

很简单,输入

exit

你会发现终端窗口此时马上关闭了!也就意味着,第二个bash在之前已经退出了!

其实我们不需要用exit这么麻烦的命令来校验,只需要简单地输入

ps

就可以看到,当前有多少个bash。

BLFS第23章配置X window系统的代码错了吗?

从前面的校验可以看出,没有错!
那么,为什么有的人把那些代码制作成脚本,会不按预想的方式执行呢?

首先是:他们没有按照BLFS手册的要求去做!

可以看看手册的原文,或者也可以到
http://svn.gooth.cn/blfs/当前

看看我翻译好的X window那一章。

原文的要求是,在终端下输入下面的命令(或者类似的)
是“输入”而不是放在一个脚本中执行!这两者“有所不同”!

我知道有的人一定是把命令复制粘贴到了一个文件中,比如temp,然后试图运行

source temp

来达到预期的结果。但是,这种做法根本不能达到目的!

根本原因就是:上面那个脚本文件中的所有命令,是在第一个shell中运行的,而不是第二个。

于是,运行的结果就会是打开一个带-e参数的bash。然后脚本就会等待。等到这个bash退出以后,才会运行接下来的命令。这也就达不到出错退出的要求了。

那么,我确实想用脚本,怎么办?

两种办法:

一、把脚本的第一行bash -e去掉。先运行
bash -e
等进入到第二个shell中后,再
source temp
就没有问题了。

二、用shell编程风格的脚本,就是第一行为:
#!/bin/bash -e
并把脚本的权限变为可执行。
这样输入
./temp
也没有问题,可以正常执行。

原因就是:shell编程脚本,本身的意义就是,打开第一行要求的shell,并用这个shell执行接下来的语句。


长篇大论的,希望大家不要怪我卖弄。吃饭去也!祝各位成功做出BLFS。
回复 支持 反对

使用道具 举报

发表于 2008-10-25 13:11:45 | 显示全部楼层
呵呵~~ ti8er 说的相当不错~~~

一开始没明白到底哪里出问题了,呵呵,原来是
/bin/bash V.S. #!/bin/bash
回复 支持 反对

使用道具 举报

发表于 2008-10-25 13:34:20 | 显示全部楼层
ti8er 是当老师的?
回复 支持 反对

使用道具 举报

发表于 2008-10-25 13:44:50 | 显示全部楼层
Post by d00m3d;1899067
ti8er 是当老师的?


我不是老师,不过经常上课呵呵。是业余的。备课很辛苦地。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表