2017-02-24 86 views
0

这里是myscript.sh内容:打击 “严格” 模式,箭头(>)运算符

#!/bin/bash 
set -euo pipefail 

# bar is an unexisting command 
bar > test 

当我调用./myscript.sh我收到以下错误消息(预计),

./myscript.sh: line 5: bar: command not found 

但空的test文件被创建:

-rw-r--r-- 1 spg staff  0B 23 Feb 16:32 test 

我认为通过激活“严格“模式(使用set -euo pipefail的组合),找不到bar命令的失败将在此时停止脚本执行,而不继续创建空的test文件。

我想知道我怎么能防止test文件的创建如果表达式为>运营商的左侧(在这种情况下,bar)失败。

+2

BTW,不像Perl的严格模式,无论是'设置-eu'其实是一个不错的主意是...一个非常有争议的和持续的辩论。参见[BashFAQ#105](http://mywiki.wooledge.org/BashFAQ/105)(描述了'set -e'的一些无意的后果)和[BashFAQ#112](http://mywiki.wooledge .org/BashFAQ/112)(描述'set -u'的一些非预期后果)。 –

+0

@CharlesDuffy这些是非常有趣的文章,感谢分享 – spg

+0

Bash中的严重错误处理需要(1)陷阱错误,而不是使用'set -e'和(2)创建一种方法来处理为什么我在每个级别调用“exceptions”在调用层次结构中。完成之后,它允许您的脚本分辨明确处理的故障情况和错误之间的区别。它最终看起来像一个try/catch机制。它需要比大多数人愿意投资更多的shell代码(和更多的管理),但是它是可行的,可重用的,并且一旦实现,您就可以摆脱由于函数内部错误导致的返回代码的逻辑运算符的暴政。 – Fred

回答

2

重定向在进程调用之前完成,以便它的stdout(在本例中)可以连接到文件。这就是为什么test被创建,即使bar不存在。它不知道在设置重定向时调用该命令会失败。

我不认为有一种直接的方法可以避免在使用重定向时创建文件。你可以尝试测试做,比如说bar能否成功首先,

if command -v bar; then 
    bar > test 
else 
    exit 1 # or whatever you want since the command would have failed 
fi 
+1

我实际上会反转这个:'如果!命令-v栏;然后退出1; fi'并将其放在脚本的开头。一旦你确认了任何关键命令的存在,脚本的其余部分可以编写,并知道任何错误不会由于缺少命令而导致。 – chepner