2017-02-24 21 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