为什么在源脚本中,“ exec不存在的文件”会退出外壳?

阿列克谢·亚历山德罗夫(Alexey Alexandrov)

的文档exec说,如果当前外壳是非交互式的并且execfail未设置选项,则在出现错误的情况下它将退出外壳

我注意到交互式bash shell中有一个奇怪的行为,但是我无法用文档来解释。这个命令

exec non-existent-file

产生错误消息,并且外壳程序保持活动状态,如预期的那样。但是,如果我将相同的命令放入文件和source该文件中,则当前的shell将由失败的exec退出。

有人可以帮我理解为什么会这样吗?

约翰·韦斯特

据我所知,这是一个错误。以下是某种“侦探小说”。

是的,在exec.def代码中,我们看到:

if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
  exit_shell (exit_value);

因此,exec将导致退出外壳a)在非交互式外壳上使用false“ no_exit_on_failed_exec” b)exec在子外壳中运行时

对于交互式外壳程序,如果存在该命令,则该外壳程序将由调用的命令替换:

执行

这个内置的shell用指定的命令替换当前进程。通常,当外壳程序遇到命令时,它将派生一个子进程来实际执行该命令。使用内置的exec,shell不会派生,并且exec'命令替换了shell因此,当在脚本中使用时,当exec'ed命令终止时它会强制退出脚本

示例15-24 执行的影响

#!/bin/bash
exec echo "Exiting \"$0\" at line $LINENO."   # Exit from script here.
# $LINENO is an internal Bash variable set to the line number it's on.
**# The following lines never execute.**

http://www.tldp.org/LDP/abs/html/internal.html#EXECREF

sourcecommand不调用subshel​​l-强制所有命令在您当前的活动shell中执行(例如,用于设置变量-不是要退出的某些subshel​​l,而是您当前的shell)。因此source,在shell中直接执行命令之后,shell将终止(这是预期的行为)。

当使用`source'运行脚本时,它将在现有的shell中运行,脚本完成后,由脚本创建或修改的任何变量将保持可用。http://ss64.com/bash/source.html

我已经编译bash-4.2并在gdb调试器中运行了它

这些是退出前要执行的最后命令:

(gdb) 
bash: exec: non-existing-file: не найден
163       exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */
(gdb) 
165       goto failed_exec;
(gdb) 
235   FREE (command);
(gdb) 
237   if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
(gdb)
238     exit_shell (exit_value);
(gdb)
[Inferior 1 (process 4034) exited with code 0177]

打印变量:

(gdb) p subshell_environment 
$1 = 0
(gdb) p interactive
$2 = 0
(gdb) p no_exit_on_failed_exec 
$3 = 0

事实证明,interactive=0在采购内置组件时,外壳是非交互式()的exec这就是这种行为的原因。它与记录的行为相矛盾,因此,也许有人会说,您发现了一个错误。

non-interactive的更改interactive=0发生在此处(evalfile.c):

interactive:
Old value = 1
New value = 0
_evalfile (filename=0xa014c8 "exec1.sh", flags=14)
at evalfile.c:226
223  if (flags & FEVAL_NONINT)
224    interactive = 0;

因为flags=14flags在功能source_fileevalfile.c中设置为更高的级别

#1  0x0000000000485dcf in source_file (filename=0x9fb8c8 "exec1.sh", sflags=0)

338  flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
339  if (sflags)
340    flags |= FEVAL_NOPUSHARGS;
341  /* POSIX shells exit if non-interactive and file error. */
342  if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0)
343    flags |= FEVAL_LONGJMP;
344  rval = _evalfile (filename, flags);

定义是:

#define FEVAL_BUILTIN       0x002
#define FEVAL_UNWINDPROT    0x004
#define FEVAL_NONINT        0x008

->标志1110 = 14。

所以,按照我的理解,这是一个错误:source在当前shell执行命令,但套旗FEVAL_NONINT 0x008-非交互式(错误这里):evalfile.csource_file

338 flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;

我在错误跟踪器上创建了一个问题:

http://savannah.gnu.org/support/index.php?108980

会看的。


编辑1:作为bash支持者在票证上评论

“尽管外壳本身是交互式的(interactive_shell == 1),但是当读取源内置文件的文件参数时,外壳当前不是交互式的(交互式== 0)。”

而且,正如他所说,这种行为在不久的将来很可能不会改变。

这个问题似乎已经结束。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从子外壳退出外壳脚本

来自分类Dev

PHP:如果文件不存在,则退出脚本

来自分类Dev

为什么脚本中不存在Camera?

来自分类Dev

Perl:如果文件中不存在特定行,则退出

来自分类Dev

为什么在Amazon SDK中请求不存在的文件的预签名URL会返回URL?

来自分类Dev

为什么Ctrl-D(EOF)退出外壳?

来自分类Dev

在bash中,退出脚本而不退出外壳,或者从子外壳中导出/设置变量

来自分类Dev

为什么`source foo && true`会退出bash中的脚本?

来自分类Dev

在统一的C#脚本中,为什么输入不存在?

来自分类Dev

为什么NetworkManager试图控制不存在的接口脚本?

来自分类Dev

为什么存在/不存在HsColour二进制文件会强制重新编译QuickCheck库?

来自分类Dev

为什么设置CosmosDBthroughputSettings会导致“系统中不存在具有指定ID的实体”?

来自分类Dev

为什么grails源不在/ src文件夹中?

来自分类Dev

如果我尝试读取一个不存在的文件会抛出什么异常?

来自分类Dev

为什么Configuration.FilePath返回不存在的文件?

来自分类Dev

为什么我要写入的文件“不存在”?

来自分类Dev

为什么我得到的文件名不存在?

来自分类Dev

为什么现有文件不存在?

来自分类Dev

为什么我得到的文件名不存在?

来自分类Dev

如果远程服务器上不存在文件或磁盘已满,则从子 shell 退出 shell 脚本?

来自分类Dev

Java中的文件不存在异常

来自分类Dev

文件在“ locate”命令中显示,但不存在。为什么?

来自分类Dev

为什么不能删除“不存在”但出现在我的下载目录中的文件?

来自分类Dev

为什么开普勒4.3中不存在创建“新xml文件”的问题?

来自分类Dev

rsync从源中删除文件夹,如果源中不存在

来自分类Dev

为什么C ++中不存在引用成员的功能?

来自分类Dev

为什么C#中不存在吊装?

来自分类Dev

为什么[分支“开发”]在.git / config中不存在?

来自分类Dev

为什么JavaScript中不存在clientRight或clientBottom?

Related 相关文章

  1. 1

    从子外壳退出外壳脚本

  2. 2

    PHP:如果文件不存在,则退出脚本

  3. 3

    为什么脚本中不存在Camera?

  4. 4

    Perl:如果文件中不存在特定行,则退出

  5. 5

    为什么在Amazon SDK中请求不存在的文件的预签名URL会返回URL?

  6. 6

    为什么Ctrl-D(EOF)退出外壳?

  7. 7

    在bash中,退出脚本而不退出外壳,或者从子外壳中导出/设置变量

  8. 8

    为什么`source foo && true`会退出bash中的脚本?

  9. 9

    在统一的C#脚本中,为什么输入不存在?

  10. 10

    为什么NetworkManager试图控制不存在的接口脚本?

  11. 11

    为什么存在/不存在HsColour二进制文件会强制重新编译QuickCheck库?

  12. 12

    为什么设置CosmosDBthroughputSettings会导致“系统中不存在具有指定ID的实体”?

  13. 13

    为什么grails源不在/ src文件夹中?

  14. 14

    如果我尝试读取一个不存在的文件会抛出什么异常?

  15. 15

    为什么Configuration.FilePath返回不存在的文件?

  16. 16

    为什么我要写入的文件“不存在”?

  17. 17

    为什么我得到的文件名不存在?

  18. 18

    为什么现有文件不存在?

  19. 19

    为什么我得到的文件名不存在?

  20. 20

    如果远程服务器上不存在文件或磁盘已满,则从子 shell 退出 shell 脚本?

  21. 21

    Java中的文件不存在异常

  22. 22

    文件在“ locate”命令中显示,但不存在。为什么?

  23. 23

    为什么不能删除“不存在”但出现在我的下载目录中的文件?

  24. 24

    为什么开普勒4.3中不存在创建“新xml文件”的问题?

  25. 25

    rsync从源中删除文件夹,如果源中不存在

  26. 26

    为什么C ++中不存在引用成员的功能?

  27. 27

    为什么C#中不存在吊装?

  28. 28

    为什么[分支“开发”]在.git / config中不存在?

  29. 29

    为什么JavaScript中不存在clientRight或clientBottom?

热门标签

归档