+ -
当前位置:首页 → 问答吧 → bash -e #exit on all errors如何理解?感谢ti8er解惑

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

时间:2008-10-24

来源:互联网

我在BLFS6.3手册的xorg7章节看到一个脚本范例
开头就是bash -e #exit on all errors

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

http://www.linuxfromscratch.org/blfs...e/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楼精彩回复

作者: ppluer   发布时间: 2008-10-24

出错就退出。

作者: 晨想   发布时间: 2008-10-24

引用:
作者: 晨想
出错就退出。
为什么没有错误就根本不执行呢?

还是说结尾+ exit就可以 明天试下

作者: ppluer   发布时间: 2008-10-24

这里面不好理解的多了, 不抄代码光思考的人们不知道啊,咱这抄代码的问问吧, 呵呵, 弄不好还被楼上的楼上的锁帖子说无聊

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

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

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

作者: wangjt   发布时间: 2008-10-24

引用:
作者: wangjt
这里面不好理解的多了, 不抄代码光思考的人们不知道啊,咱这抄代码的问问吧, 呵呵, 弄不好还被楼上的楼上的锁帖子说无聊

我觉得这代码是有问题的, 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确实有点不妥
谢谢二位

作者: ppluer   发布时间: 2008-10-24

引用:
作者: wangjt
这里面不好理解的多了, 不抄代码光思考的人们不知道啊,咱这抄代码的问问吧, 呵呵, 弄不好还被楼上的楼上的锁帖子说无聊

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

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

我是个菜鸟,上边是我猜的
唉,怎么又是你说代码有问题啊……

没有任何问题!

等下我来解释。

作者: ti8er   发布时间: 2008-10-25

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。

作者: ti8er   发布时间: 2008-10-25

呵呵~~ ti8er 说的相当不错~~~

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

作者: grissiom   发布时间: 2008-10-25

ti8er 是当老师的?

作者: d00m3d   发布时间: 2008-10-25

引用:
作者: d00m3d
ti8er 是当老师的?
我不是老师,不过经常上课呵呵。是业余的。备课很辛苦地。

作者: ti8er   发布时间: 2008-10-25

谢谢 解释的很精彩 受教了

作者: ppluer   发布时间: 2008-10-27

引用:
作者: ti8er
bash -e 是什么?

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

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

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

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

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

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

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

source temp

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

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

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

附上6.2版BLFS手册原文 ---ti8er兄翻译的BLFS/X章节在哪里可以看到 您给的地址似乎打不开
Additionally, because of the large number of repetitive commands, you are encouraged to script the build. For most sections, you can use a script with commands similar to the following, to compile and install all packages in a wget file list:
bash -e #exit on all errors
for package in $(cat ../wgetlist.wget)
do
packagedir=$(echo $package | sed 's/.tar.bz2//')
tar -xf $package
cd $packagedir
./configure $XORG_CONFIG
make
make install
cd ..
rm -rf $packagedir
rm -f $package
done 2>&1 | tee -a ../xorg-compile.log #log the entire loop
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.

作者: ppluer   发布时间: 2008-10-27

在看命令的时候,记得要看英文说明,有的时候命令并没有写出来,但是说明中告诉你了。

ti8er 的解释很赞,精华一下:)

作者: 晨想   发布时间: 2008-10-27

请看BLFS6.3的原文。6.2的可能有点小问题。

第23章:Introduction to Xorg-7.2

The commands below (or similar) can be entered at the command line to compile each group of packages (proto, utils, libs, apps, drivers).

我翻译的BLFS的地址好像又改了,html变成xml了,但是网管又不更新好,以前的劳动都不知道去哪里了,真烦。好在我本机上还有已经翻译好的html。

作者: ti8er   发布时间: 2008-10-27

引用:
作者: ti8er
请看BLFS6.3的原文。6.2的可能有点小问题。

第23章:Introduction to Xorg-7.2

The commands below (or similar) can be entered at the command line to compile each group of packages (proto, utils, libs, apps, drivers).

我翻译的BLFS的地址好像又改了,html变成xml了,但是网管又不更新好,以前的劳动都不知道去哪里了,真烦。好在我本机上还有已经翻译好的html。
我以为BLFS6.3/6.2 都是xorg7.2没差呢呵呵

作者: ppluer   发布时间: 2008-10-27

精彩!顶下!

作者: epvmm365   发布时间: 2009-10-16

引用:
作者: ti8er
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。
我知道有的人一定是把命令复制粘贴到了一个文件中,比如temp,然后试图运行

source temp

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

根本原因就是:上面那个脚本文件中的所有命令,是在第一个shell中运行的,而不是第二个。
-------------------------------------------------
异议:
1)
source temp好像并不是打开新大SHELL来执行的temp.
我在temp中,仅有一个set
看到SHLVL=4与执行source temp前一样,但bash temp的结果是SHLVL=5(打开一个新的shell来执行)。
2)不成功的原因,可能正正是他们使用了source temp的形式执行,如果
bash -e temp
可能就会成功。我没有试过。按文分析这样就可以打开新的shell执行,符合原文要求。

作者: zswlb9999   发布时间: 2009-10-16

太佩服ti8er了,我觉得讲得非常好,深入浅出,入木三分,哈哈,精僻

作者: qdog988   发布时间: 2009-10-17

明明是让你开一个子shell,然后把下面的命令放到子shell里面执行,不是让你在脚本里面这样干:
代码:
bash -e
# Do something
bash -e
# Do something
...
而是
代码:
bash -e << '!End-Of-File!'
# Do something
!End-Of-File!

作者: tusooa   发布时间: 2009-10-24

#!/bin/bash -e
very good !

作者: 鸟儿   发布时间: 2009-10-24

热门下载

更多