LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: ppluer

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

[复制链接]
 楼主| 发表于 2008-10-26 22:15:28 | 显示全部楼层
谢谢 解释的很精彩 受教了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-10-26 22:30:24 | 显示全部楼层
Post by ti8er;1899027
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.
回复 支持 反对

使用道具 举报

发表于 2008-10-27 03:00:59 | 显示全部楼层
在看命令的时候,记得要看英文说明,有的时候命令并没有写出来,但是说明中告诉你了。

ti8er 的解释很赞,精华一下:)
回复 支持 反对

使用道具 举报

发表于 2008-10-27 09:10:47 | 显示全部楼层
请看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。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-10-27 13:24:48 | 显示全部楼层
Post by ti8er;1899849
请看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没差呢呵呵
回复 支持 反对

使用道具 举报

发表于 2009-10-16 11:44:04 | 显示全部楼层
精彩!顶下!
回复 支持 反对

使用道具 举报

发表于 2009-10-16 18:10:16 | 显示全部楼层
Post by ti8er;1899027
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执行,符合原文要求。
回复 支持 反对

使用道具 举报

发表于 2009-10-16 20:36:37 | 显示全部楼层
太佩服ti8er了,我觉得讲得非常好,深入浅出,入木三分,哈哈,精僻
回复 支持 反对

使用道具 举报

发表于 2009-10-24 17:01:59 | 显示全部楼层
明明是让你开一个子shell,然后把下面的命令放到子shell里面执行,不是让你在脚本里面这样干:

  1. bash -e
  2. # Do something
  3. bash -e
  4. # Do something
  5. ...
复制代码
而是

  1. bash -e << '!End-Of-File!'
  2. # Do something
  3. !End-Of-File!
复制代码
回复 支持 反对

使用道具 举报

发表于 2009-10-24 19:05:12 | 显示全部楼层
#!/bin/bash -e
very good !
回复 支持 反对

使用道具 举报

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

本版积分规则

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