如果重定向失败,则不执行 Bash 程序

Cha*_*ass 9 shell bash io-redirection error-handling

在 bash 中,我注意到如果使用重定向的命令失败,则在此之前运行的任何程序都不会运行。

例如,此程序打开文件“a”并向文件“a”写入 50 个字节。但是,在重定向到权限不足的文件 (~root/log) 的情况下运行此命令,“a”的文件大小不会发生变化。

$ ./write_file.py >> ~root/log
-bash: /var/root/log: Permission denied
cdal at Mac in ~/experimental/unix_write
$ ls -lt
total 16
-rw-rw-r--  1 cdal  staff  0 Apr 27 08:54 a <-- SHOULD BE 50 BYTES
Run Code Online (Sandbox Code Playgroud)

有人会认为程序会运行,捕获任何输出(但也会写入文件“a”),然后无法将任何输出写入 ~root/log。相反,该程序永远不会运行。

为什么会这样,bash 如何在执行程序之前选择它执行的“检查”的顺序?是否也进行了其他检查?

ps 我试图确定在 cron 下运行的程序在重定向到“权限被拒绝”文件时是否实际运行。

Ste*_*itt 18

这不是排序检查的真正问题,只是外壳程序设置的顺序。在命令运行之前设置重定向;所以在你的例子中,shell~root/log在尝试做任何涉及./write_file.py. 由于无法打开日志文件,重定向失败,此时 shell 停止处理命令行。

证明这一点的一种方法是获取一个不可执行的文件并尝试运行它:

$ touch demo
$ ./demo
zsh: permission denied: ./demo
$ ./demo > ~root/log
zsh: permission denied: /root/log
Run Code Online (Sandbox Code Playgroud)

这表明./demo当无法设置重定向时,shell 甚至不查看。

  • 如果他们不先完成,输出会写到哪里? (6认同)

Mur*_*phy 11

从bash 手册页,重定向部分(我强调):

在执行命令之前,可以使用由 shell 解释的特殊符号重定向其输入和输出。

...

打开或创建文件失败会导致重定向失败。

因此,shell 尝试打开目标文件 for stdout,但失败了,并且根本不执行该命令。