公司開發的Android應用,由於在不一樣平臺下簽名文件不同,須要分別進行簽名,這個很麻煩,因而要求在公司的後臺管理系統中可以對上傳的APK文件,自動使用不一樣平臺的簽名文件完成簽名,這樣只須要上傳一次文件就獲得全部平臺簽名後的APK了,分發起來方便很多。php
具體如何對APK文件進行簽名,網上有不少文章,請自行搜索。考慮到整個簽名過程使用的命令比較多,因而寫了個腳原本完成簽名,這樣在PHP中只須要經過exec()函數執行這個腳本就行了。java
思路是沒錯的,可是寫好了腳本之後,PHP執行腳本的時候卻出了問題,windows下的腳本沒有問題,linux的腳本不行,exec()的output參數返回爲{},查看後臺文件發現也確實沒有生成簽名文件。linux
遂對後臺腳本逐行註釋,最終發現是在執行jar、jarsigner命令時失敗,這幾個命令根本沒有被執行,在網上搜了半天,發現說法大多以下:nginx
一、 權限不夠,要提高PHP exec()的權限爲sudo,且要免密碼;
windows
二、 PHP exec()只能執行系統原生命令,不能執行後面安裝的第三方應用的命令;
ide
對於說法1,試用了以下方法:函數
一、 設置php-fpm.conf的user參數爲root,用php-fpm –R命令啓動PHP,此時php-fpm進程的用戶爲root;php-fpm
二、 php-fpm默認用戶爲nginx,將該用戶添加到sudoers,且設置爲免密碼;spa
以上方法均驗證失敗。orm
最後偶然發現,原來不是權限問題,也不是exec()只能執行原生命令,原來是路徑問題,原本已經將jar、jarsigner命令添加到系統PATH參數下了,可是不知道爲何,在exec()函數中彷佛沒有識別PATH參數,也就沒有找到jar、jarsigner命令,因此致使簽名失敗,最終的腳本以下(紅色部分代碼是特地爲第三方命令添加路徑的):
#SOR_NAME=FlyingStone-v2.0.4 #SOR_FILE=$SOR_NAME.apk #PASS=By51096188 #KEY_STORE=beyondscreen.keystore #PLAT_FORM=samsung #KEY_STORE_ALIAS=bygame DIR="$1" SOR_NAME="$2" PASS="$3" KEY_STORE="$4" PLAT_FORM="$5" KEY_STORE_ALIAS="$6" SOR_FILE=$SOR_NAME.apk JAVA_BIN=/usr/local/java/jdk1.8.0_144/bin #進入到工做目錄,待簽名APK在這個目錄下 cd $DIR #創建temp子目錄,且將待簽名APK拷貝到temp子目錄 if [ -d temp ]; then rm -rf temp fi mkdir temp cp $SOR_FILE temp/$SOR_FILE #進入temp子目錄,將待簽名APK解壓,並刪除META-INF子目錄下原來的簽名文件 #由於若是帶有簽名文件,會致使簽名失敗 cd temp "$JAVA_BIN"/jar -xf $SOR_FILE rm $SOR_FILE cd META-INF rm -f *.RSA rm -f *.SF cd .. #將temp目錄下的文件從新打包爲新的APK文件,用來進行簽名 "$JAVA_BIN"/jar -cvf0 ../"$SOR_NAME"_new.apk ./ cd .. #對新的APK文件進行簽名 "$JAVA_BIN"/jarsigner -verbose -storepass $PASS -keystore $KEY_STORE -signedjar "$SOR_NAME"-signed-"$PLAT_FORM".apk "$SOR_NAME"_new.apk $KEY_STORE_ALIAS rm "$SOR_NAME"_new.apk rm -f -R temp |