printf程式可以用來列印二進制資料,例如:
$ printf '%b'/span> 'xffxff'
??
如果我把這個單獨放在一個Makefile中,它的作業原理是一樣的:
如果我把這個單獨放在一個Makefile中,它的作業原理是一樣的。
all:
printf '%b'/span> 'xffxff'/span>
$ make
printf '%b'/span> 'xffxff'/span>
??
但是,如果我想在Makefile中的同一個shell呼叫上做其他事情,例如將其重定向到一個檔案,或者只是在之后列印其他東西,那么盡管Make列印的命令沒有變化(表明這不是一個轉義問題),但是輸出卻變成了一個反斜杠,后面是一個 "x",后面是一個雙 "f",兩次:
all:
printf '%b' 'xffxff'; printf'wtf?
'
make
printf '%b' 'xffxff'; printf'wtf?
'
xffxffwtf?
這里發生了什么?為什么一行中的兩個printf的行為與一個printf的行為不同?
uj5u.com熱心網友回復:
@chepner在他們的評論中是正確的,但細節不甚正確。
Make 總是使用 /bin/sh 作為它的 shell,不管用戶使用什么作為他們的 shell。 在一些系統中,/bin/sh是bash(它有一個內置的printf),而在一些系統中,/bin/sh是不同的東西(通常是dash,這是一個輕量級的、符合POSIX的shell),它可能沒有一個內置的shell。
在你的系統中,/bin/sh是bash。 但是,當你有一個不需要shell的 "簡單命令 "時(也就是說,make本身有足夠的瑣碎的參考智能來理解你的命令),為了提高效率,make將直接呼叫該命令而不是運行shell。
這就是這里發生的事情:當你運行簡單的命令(沒有;)時,make將直接呼叫該命令并運行/usr/bin/printf。 當你運行更復雜的命令(包括一個;)時,make將放棄直接運行該命令而呼叫你的shell...也就是bash,它使用bash的內置printf。
基本上,你的腳本不符合POSIX標準(POSIX標準中沒有%b),所以它所做的事情沒有被很好地定義。 如果你想永遠使用相同的行為,你應該使用/usr/bin/printf來強制使用該行為。 迫使make總是運行一個shell而不使用它的快速路徑要棘手得多;你需要在每個命令中包含一個特殊的字符,如尾部的;。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/309910.html
標籤:
