問題描述
從git倉庫更新了別人配置好的logrotate,發現不能正常運行。手工執行報錯
error: Ignoring syslog because of bad file mode - must be 0644 or 0444
具體看了下,確實有個配置文件,是664。手工執行chmod 修改權限后,就可以運行了。但這個提交之前確實時有測試過的,為什么經過上傳下載后,就不行了呢?到倉庫中去,執行下chmod想修正下權限提交,發現chmod之后git卻沒檢測到有修改。趕緊google學習下。
文件權限位
先簡介下權限位。
linux文件具有權限位屬性。一般是用三個數字表示,例如755,664,644等。
三個數字分別代表,文件所有者的權限,與文件所有者同一組的用戶的權限,不與文件所有者同組的其他用戶的權限。
具體的每個數字,是代表了讀寫執行(rwx)三種權限。
7轉換為二進制是0b111,即代表有讀寫執行權限。
6轉換為二進制是0b110,代表有讀寫權限,無執行權限。
4轉換成二進制是0b100,代表有讀權限,無寫和執行權限。
ls -l 即可看到某個文件的具體權限。
chmod 可改變某個文件的權限。
git倉庫對權限位的處理
重點來了,權限位包括了讀寫執行,但git倉庫並不記錄全部權限位。
當 git config core.fileMode 為true時,git會記錄該文件是否是可執行的。即當你chmod將文件從664改為755時,git可以檢測到修改,你也可以添加提交這個改動。
但git只記錄執行權限,而不記錄讀寫權限。
換句話說,644的文件和664的文件,對git來說是沒區別的。
這就是問題的原因了。提交者本地修改完測試的時候,權限位已經改成644,測試了logrotate沒問題才提交上去,其他人下載下來卻變成了664,無法正常運行。
什么決定了下載下來的文件權限
既然git中不記錄讀寫權限,那么為什么下載下來時664,而不是644,666,444等其他權限呢?
答案是,跟每個人本地設定的umask有關。
umask設置了用戶創建文件的默認權限補碼。
在控制台輸入umask命令,可以打印出當前的umask值。
umask=002時, 創建的文件默認為664(666-002),文件夾默認為775(777-002)
umask=022時,創建的文件默認為644(666-022),文件夾默認為755(777-022)
怎么解決logrotate的這個問題
回到問題本身,大部分時候,我們不必關心644和664的區別。但出現了logrotate這種必須644的情況時,也不可能通知到每個人,手工去chmod或者修改每台電腦上的umask,還是要在SDK中解決。既然git不記錄,那就要靠編譯系統了。
例如openwrt中,就已經定義了一系列的命令。在寫包的makefile時盡量規范些,根據產物的不同,選用合適的INSTALL_XXX命令,安裝到rootfs中,就可以避免這個問題了。
INSTALL_BIN:=install -m0755
INSTALL_DIR:=install -d -m0755
INSTALL_DATA:=install -m0644
INSTALL_CONF:=install -m0600
如果確實很特殊,那就特殊處理下了,手工在對應makefile中加個chmod。
參考
stackoverflow問題:git-pull-is-setting-664-instead-of-644-permissions