2010-08-13 76 views
7

我有一個創建一個目錄中的規則禁止化妝規則錯誤輸出

bin: 
    -mkdir [email protected] 

但是已經生成的目錄後的第一時間,我收到這樣的輸出:

mkdir bin 
mkdir: cannot create directory `bin': File exists 
make: [bin] Error 1 (ignored) 

有一些方法如果目錄不存在,我只能運行規則,或者在目錄已經存在的情況下禁止輸出?

+0

Near duplicate:http://stackoverflow.com/questions/3477292/what-do-and-do-as-prefixes-to-recipe-lines-in-make – reinierpost 2010-08-24 07:52:21

回答

8

傳統的方式來處理目錄的創建是使用的依賴,並創建目錄的副作用郵票文件。使distclean或任何時候取出印章的文件你的「真乾淨」的目標是:

bin/.dirstamp: 
    mkdir -p $(DIRS) 
    touch [email protected] 

bin/foo: bin/.dirstamp 
    $(MKFOO) -o [email protected] 

distclean: 
    rm -rf bin 

其原因如下:每當創建於bin文件/刪除,包含目錄的mtime更新。如果目標取決於bin,則下次運行make時,它將重新創建不需要的文件。

+0

dir dep是否生成所有生成到該位置的文件? – 2010-08-24 13:18:21

+0

在該目錄中創建的每個文件都需要直接或間接地依賴於圖章文件,以確保它在使用前創建。 – 2010-08-24 13:37:09

7

錯誤在命令行上已被領先的'-'忽略。如果你真的想從mkdir失去了錯誤信息,使用I/O重定向:

bin: 
    -mkdir bin 2> /dev/null 

你仍然會得到「忽略」從make警告,雖然如此,它可能是更好的使用該選項mkdir不會導致當目標已經存在,這是-p選擇它失敗:

MKDIR_P = mkdir -p 

bin: 
    ${MKDIR_P} [email protected] 

-p選項實際上是創建所有缺少對特定的路徑的目錄,因此它可以產生的AA號碼目錄在一次調用,但作爲ide-effect是它不會爲已經存在的目錄產生錯誤。這確實假定了一個POSIX-ish實現mkdir;舊的機器可能不支持它(儘管它現在已經很長時間是標準的)。

+0

爲什麼這樣的'2&1'重定向有幫助?我會理解'2/dev/null'發送stderr遺忘,但發送到標準輸出.....? – humanityANDpeace 2016-03-09 19:22:36

+0

@humanityANDpeace:你是對的 - 在2010年回想一下。我已經修復了它。謝謝。 – 2016-03-09 20:59:19

0

你的規則不應該被執行,除非它的目標不存在,或者因爲它的依賴性而過時。換句話說,你不應該遇到這個錯誤。

[例新增]

[[email protected] tmp]$ ls -la 
total 20 
drwxr-xr-x. 2 max users 4096 Aug 14 21:11 . 
drwx------. 80 max max 4096 Aug 14 18:25 .. 
-rw-rw-r-- 1 max max  38 Aug 14 21:11 Makefile 
[[email protected] tmp]$ cat Makefile 
.PHONY: all 
all: bin 

bin: 
    mkdir [email protected] 

[[email protected] tmp]$ make 
mkdir bin 
[[email protected] tmp]$ ls -la 
total 24 
drwxr-xr-x. 3 max users 4096 Aug 14 21:11 . 
drwx------. 80 max max 4096 Aug 14 18:25 .. 
drwxrwxr-x 2 max max 4096 Aug 14 21:11 bin 
-rw-rw-r-- 1 max max  38 Aug 14 21:11 Makefile 
[[email protected] tmp]$ make 
make: Nothing to be done for `all'. 
[[email protected] tmp]$ make 
make: Nothing to be done for `all'. 

請問您的文件夾取決於什麼?你的文件夾是假目標嗎?

+0

沒有。它總是過時,你在OP中看到的是我所擁有的。 – 2010-08-14 01:27:05

0

嗯,我結束了這個結構,也許有人會覺得它有用或者它可以發表評論:

BINDIR = . 
TMPDIR = tmp 
OUTDIRS = $(BINDIR) $(TMPDIR) 
$(OUTDIRS): 
    @test -d [email protected] || mkdir [email protected] 
+0

無論如何make都會爲你測試,所以它最終將目錄統計爲兩次。這只是隱藏了默認目標是。(點)的問題。 – 2010-08-20 16:27:47

0

製作假定的第一個目標是缺省目標。如果這是你的完整makefile,那麼它一定總是試圖重新設置bin的默認目標。插入以下行到你的Makefile頂部:

all: bin 
.PHONY: all 
12

抑制make: error ... (ignored)輸出的另一種方法是將|| true附加到可能失敗的命令。使用grep的例子,檢查在LaTeX的日誌文件中的錯誤:

undefined: 
    @grep -i undefined *.log || true 

沒有|| true,使grep的時候沒有找到任何匹配抱怨。

這適用於所有命令,而不僅僅是mkdir;這就是爲什麼我添加了這個答案。

+0

daniel,make規則中的命令的'-'前綴字符可以做同樣的事情,儘管不需要shell來處理它。這可能會更快,並且適得其反。 – 2012-04-16 17:52:03

+7

'-'前綴會導致make輸出令人討厭的「錯誤忽略」輸出,而我的解決方案不會。所以不,這兩個人不會做同樣的事情。 – 2012-04-17 06:33:03

+0

公平的電話。謝謝 – 2012-04-18 07:08:35