首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >bash时间的奇怪交互,设置-e和false,bash 3与bash 4的差异

bash时间的奇怪交互,设置-e和false,bash 3与bash 4的差异
EN

Stack Overflow用户
提问于 2012-10-23 14:21:57
回答 1查看 257关注 0票数 2

下面是time falseset -e下的成功秘诀(在某种意义上,time输出是成功的):

代码语言:javascript
复制
(
set +e
time { ( set -e; false; echo no0; ); }
echo yes0 $?
)

但是下面的菜谱失败了:

代码语言:javascript
复制
(
set -e
time false
echo no1
)

此外:

代码语言:javascript
复制
(
set -e
time { false; echo no2; }
echo no2
)

此外(令人惊讶的是,它在bash3下输出bash3,而在bash4下没有输出):

代码语言:javascript
复制
(
set -e
time ( false; echo no3; )
echo yes3 $?
)

也(不太令人惊讶):

代码语言:javascript
复制
(
set +e
time { set -e; false; echo no4; }
echo no4
)

还有(惊喜):

代码语言:javascript
复制
(
set +e
time ( set -e; false; echo no5; )
echo yes5 $?
)

以下是在bash3下成功并在bash4下做了完全不同的事情:

代码语言:javascript
复制
(
set -e
time { ( false; echo no7; ); echo yes6 $?; }
echo yes6 $?
)

请注意,"no“echoes没有打印,而"yes”是由bash3输出的(但不是全部由bash4输出)。

如果您将其与set -e下的子subshell set -e处理进行比较,那么在time (...)情况下,time内置的内容似乎是与子subshell上下文一起执行的。见鬼?

测试用

代码语言:javascript
复制
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

输出

代码语言:javascript
复制
real    0m0.000s
user    0m0.001s
sys     0m0.000s
yes0 1
yes3 1
yes5 1
yes6 1

real    0m0.000s
user    0m0.000s
sys     0m0.001s
yes6 0

代码语言:javascript
复制
GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.

输出

代码语言:javascript
复制
real    0m0.001s
user    0m0.000s
sys     0m0.004s
yes0 1
yes5 1

请注意,"yes3“和"yes6”两种情况显示了bash3和bash4处理set -e的方式有很大的不同。

但"yes5“一案令人困惑。看起来“时间”是由子壳处理的,而不是在外壳中处理的。

这种行为是由POSIX强制执行的,还是一辆巴什马车( bashs ),还是仅仅是一种特殊行为?

(谢谢;)

PS:如果你不明白为什么这不是学术性的:曾经有一个脚本在set -e下运行("yes3“没有time)。它被修改为记录一些时间信息,黑客看起来像"yes6“。但是现在bash4出现了,它需要再次修复。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-10-23 17:50:45

实际上,bash 4中的行为是可以预测的,

  • 如果当前shell或当前shell的子shell中的任何简单命令返回非零退出状态,set -e将导致您退出当前shell(要获得更详细/准确的描述,请阅读set)。
  • set -e优先于time,例如在no2情况下 (设置-e时间为false;) 在time能够完成执行之前退出子subshell,因此没有来自time的输出。

考虑到这一点,在yes5的情况下会发生什么(让我们将第一个( )称为“子subshell级别1",将第二个( )称为”级别2")。

代码语言:javascript
复制
(
    set +e
    time ( set -e; false; echo no5; )
    echo yes5 $?
)

当您遇到返回退出状态1的false时,set -e会导致它退出子subshell级别2,这会将退出状态1返回到子subshell级别1。但是,由于级别1有set +e,所以一切都会运行。

对于yes6一案,

代码语言:javascript
复制
(
    set -e
    time { ( false; echo no7; ); echo yes6 $?; }
    echo yes6 $?
)

子subshell级别2中的false返回触发set -e,因此没有输出。

剩下的留给读者做练习。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13032610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档