2019-04-19
關鍵字:Android機頂盒常用命令、Linux命令
筆者早年間從事 Android 機頂盒開發工作,那會剛畢業,技術也比較菜,工作過程中遇到過不少困難,不過所幸當時就有做筆記的習慣,很多工作過程中遇到的問題或者一些 “奇淫技巧” 都被我記錄了下來。最近學到一個新詞:復盤。恰好這段時間也在復盤自己之前的工作,發現自己雖然很長一段時間不碰機頂盒了,但之前積累下來的筆記還真不少。筆者不太甘心讓這些 “年少的自己” 就這樣塵封在暗無天日的筆記本里,加上一時間整理癖發作,就打算將它們整理成文發表出來,希望能幫到一部分后生們。
這篇文章記載的是筆者在 Android 機頂盒開發過程中經常用到的一些命令。
本篇文章提及的常用命令按 Linux 、 Android 以及 Git 三個部分來講。這些命令基本就支撐起了筆者全部的機頂盒開發過程。
1、Linux
2、Android
3、Git
1、Linux
這里的 Linux 命令有分服務器版及機頂盒版。因為機頂盒上的 Linux 系統被刪減了很多功能,因此,有些命令或參數並不適用於機頂盒。
find
find .
遍歷當前目錄。將當前目錄及其子目錄下的所有文件都列出來。
find -name init.rc find -name "init*"
首先是兩條最基本的命令,查找某文件的位置。如果要查找的文件名含有通配符,最好加上雙引號。
find -type d -name "etc*" find -type f -name "etc*"
這個是按類型查找。 -type 參數后面接 d 表示只查找目錄名,接 f 表示只查找文件名。
find /system -type f -name "ppp*"
這條命令是指定目錄查找。要指定目錄時,目錄名一定要放在最前面。
上面 4 條就是機頂盒和 Linux 服務器上通用的 find 命令了。需要注意的是機頂盒不支持直接 find ,需要通過在普通 find 命令前加上 busybox 來執行。busybox 是一個工具程序,它位於 /system/bin/busybox , 有些平台 busybox 會直接鏈到 /system/bin/toolbox 上。
下面幾條則是只在 Linux 服務器上才支持的 find 命令了。
find -maxdepth 2 -type f -name "*.mk"
設置目錄查找深度查找。這條命令表示只查找當前目錄及一級子目錄下的 .mk 文件。
find vendor/ -size +2M find system/ -size +1024k find device/ -size -20c
這幾條命令是按文件大小來查找。分別是查找大於 2M 的文件、查找大於 1024KB 的文件、查找小於 20 個字節的文件。
find vendor/ -size +2M -exec ls -alh {} \; find vendor/ -size +2M | xargs ls -alh
find vendor/ -size +20M | xargs rm -rf
前面兩條命令的執行結果是等效的。效果是將前面查找到的結果應用一下 ls -alh 命令。第 3 條命令也比較常用,查找某類文件並將它們刪除。下面那種 | xargs 格式的命令並不支持接所有指令。如果遇到不支持接的,換成第 1 種格式就可以了。
grep
grep -nr "ttyUSB" vendor/ grep -i "ttyUSB" vendor/ grep -A 5 -B 3 "ril" device/
這幾條 grep 命令撐起了我的日常工作。
第 1 條是我最常用的 grep 命令,表示在 vendor 目錄下查找包含 ttyUSB 字符串的文件,並將它們的文件名稱以及所在行數列出來。
第 2 條的 -i 參數表未忽略大小寫查找。
第 3 條表示匹配到結果以后,再往前多顯示 5 條,往后多顯示 3 條。
操作目錄
pwd pwd -L pwd -P
查看當前目錄的絕對路徑。前面兩條命令的效果是一樣的,將會顯示當前目錄的絕對路徑。 第 3 條命令顯示的是當前目錄的真實路徑,與上一條的區別就是對待 “軟鏈接” 的顯示方式了。如果當前目錄下有軟鏈接,加 -P 參數會顯示出該軟鏈接鏈向的實際路徑。
mkdir /system/myf0
mkdir -p /system/myf1/myf2
創建目錄。加個 -p 參數表示遞歸創建目錄,否則的話,只能在已存在的目錄上創建目錄。
空間統計
du -ah du -sh du -d 1 -ah
du -d 1 -ah /usr/local
統計當前目錄的空間占用情況。
第 1 條命令將會遞歸查找文件與目錄,列出每個目錄及文件的大小。參數 a 表示所有文件,參數 h 表示以適宜閱讀的形式表示其大小,如多少 KB ,多少 MB 。
第 2 條命令也是遞歸統計當前目錄所占的空間大小,只不過它不會列出每一個文件與目錄的占用情況,而是只列出一個總的結果值。
第 3 條命令則是遞歸統計當前目錄所占的空間大小,只列出當前目錄下各一級目錄的的占用空間情況,並列出當前目錄占用空間總情況。
第 4 條命令則是指定一個目錄來統計。
df -h
列出當前文件系統磁盤空間占用情況,實際作用不大,但閑着沒事時就喜歡敲敲它。
解壓縮
tar -zcvf 目錄 輸出名稱.tar.gz
tar -zcvf 目錄 | split ‐d ‐b 50m 輸出名稱.tar.gz
以 tar.gz 格式壓縮。第 2 條指令是分卷壓縮,每 50MB 分一個文件。
tar -zxvf 文件名稱.tar.gz
tar -zxvf 文件名稱.tar.gz -C 輸出目錄
解壓。對於分卷壓縮的文件,可以將它們合並成一個文件。
cat 分卷壓縮文件.tar.gz.a* > 輸出名稱.tar.gz
Linux 的分卷壓縮最后面一般都是以 aa, ab, ac 等命名的。
至於 ZIP 格式的壓縮,就不說了,筆者用的比較少。
更改權限
chmod 755 /system/bin/rild chown root:customer /system/etc/ppp/chat chgrp customer /system/bin/rild
chmod 命令用的還比較多一點。其它的,用的就很少了。Android 系統對文件權限要求比較嚴格,對某些系統關鍵文件稍微有點權限不對,編譯出來的系統都用不了。所以一般很少主動更改文件權限的。
計算 MD5
md5 /system/bin/sh
md5sum /system/bin/rild
求 MD5 值還算是比較常用的,在比對是否推錯程序時很有用處。不過不同的設備集成的 md5 計算工具可能不一樣,甚至有些系統沒有集成計算 md5 的工具。所以上面的命令其實不具備代表性。
查看進程
ps
查看系統當前進程。機頂盒開發過程中很常用的命令。
top top -d 1
查看當前系統進程及其資源占用情況。直接一個 top 是每 3 秒更新一次。加個參數 -d 1 則是每秒更新一次值。
dumpsys activity | grep Focus dumpsys activity | grep ocu
dumpsys activity -f | grep ocu
這條命令在機頂盒端也很常用,用來查詢當前處於棧頂的 Activity 名稱。上面兩條命令完全是一樣的,只不過筆者本人嫌第 1 條指令要按一個大寫的 F 麻煩,所以一般會用第 2 條,會順手很多。第 3 條是在當前活動棧中查找,其實效果都一樣。
系統屬性
這個是針對機頂盒的。
getprop ro.adb.secure getprop | grep "ril" setprop service.bootanimation.exit 1
分別是獲取屬性和設置屬性。
命令行輸入遙控器按鍵
input keyevent KEYCODE_DPAD_CENTER input keyevent 23
也比較常用的命令。可以將這些指令封裝成腳本文件來做壓力測試。
ADB
ADB 命令推文件調試非常常用啊有木有。
用這個必須要確保 adbd 進程正在運行當中,可以 ps | grep adbd 查看一下。一般默認的 adbd 端口是 5555 ,當然,有些項目為了所謂的安全,會改端口號,一般可以 getprop | grep port 查看一下。對了,好像還要確認一下 ro.adb.secure 屬性的值。在這一切前提條件都滿足以后,就可以開始使用 adb 連接了。
adb connect 192.168.x.x adb connect 192.168.x.x:17173 adb remount adb devices adb disconnect adb disconnect 192.168.x.x adb push from/file.name /to/file.name adb pull from/file.name
一般比較常用的就這些了,就不逐條解釋命令了。 adb pull 命令拉取上來的文件默認是存在電腦的用戶目錄根目錄下的。win 10 系統貌似不能指定存儲路徑。
KILL
kill 1476 kill -9 51
根據 PID 殺進程。 -9 參數把它理解成殺死一個頑固進程,哈哈。
busybox
busybox 是一個應用程序。在海思平台中,busybox 程序通常是軟鏈接到 /system/bin/toolbox 程序上的。busybox 是一個工具集,它提供的功能有很多,但常用的卻不多。
busybox ifconfig busybox ifconfig -a
上面兩條命令一般用來查看機頂盒中的網卡信息。 -a 參數是列出所有網卡信息,包括未啟用的。
busybox ifconfig eth0 hw ether 0c:c6:55:83:24:75
臨時修改 eth0 網卡的 MAC 地址。
busybox dmesg -n 1 echo 1 > /proc/sys/kernel/printk
關閉內核打印,上面兩條命令的效果是一樣的。
編譯
通常 Android 系統的編譯都離不開下面幾條命令
source build/envsetup.sh lunch xxx
這兩步是准備編譯鏈環境。
make otapackage -j32 make bigfish -j32 mm mmm vendor/xxx/app/MyApk/
這幾條就是編譯命令了。
前面兩條是編譯大包的命令,不同平台會有不同編譯參數。第 1 條是 Android 原生編譯參數,第 2 條是海思平台的編譯方式。
mm 命令是編譯當前目錄用的,需要當前目錄下有 Android.mk 文件才行。
mmm 命令則是指定目錄編譯,同樣的也需要指定的目錄下有 Android.mk 文件才行。
額外提一下,這個 mm , mmm 命令都是在 ./build/envsetup.sh 腳本中定義的函數。
通過命令恢復出廠設置
下面介紹的是海思平台通過命令恢復出廠設置的方式
1. 在 /cache 目錄下創建 recovery 目錄 2. echo --wipe_data > /cache/recovery/command 3. echo boot-recovery > /dev/block/platform/hi_mci.1/by-name/misc 4. sync 5. reboot
上述第 3 步可能會隨着版本的不同,某些目錄名稱可能會有變動,靈活應用即可。
APK 手動簽名
嚴格來講,這並不算是命令。但因為也比較常用,還是簡單提一下吧。
將 signapk.jar 文件拷貝至簽名密鑰所在的目錄。
./out/host/linux-x86/framework/signapk.jar
簽名密鑰文件不同平台的存放目錄不一樣,您可以搜索看看 platform.x509.pem 文件存儲於哪個目錄就將 signapk.jar 文件拷貝至哪個目錄。
上面步驟都准備好后,就可以通過以下命令給 APK 簽名了。事先進入到存放了簽名密鑰的目錄。
java -jar signapk.jar platform.x509.pem platform.pk8 XXX.apk XXX_signed.apk
抓日志
Android 的日志分為好幾個級別。main, system, radio, events 等。
logcat -s 標簽名稱 logcat *:E logcat -c;logcat logcat > /data/mine.log logcat -v process | grep 1471 logcat -v time -s 標簽名稱
抓取 main 級別日志。倒數第 2 條是按進程號過濾日志。最后一條是顯示日志的時間戳。也可以通過 telnetd 來遠程抓取日志,不過用的非常少,而且很多機頂盒沒有預置 telnetd 程序,所以就不說了。
logcat -b radio logcat -b logcat -c -b radio
抓取 radio 級別的日志。最后一條是清除 radio 級別的日志。
抓網絡包
tcpdump -i eth0 -s0 -w /data/player.pcap
有些機頂盒沒有預置 tcpdump 程序的。
2、Android
這一章節主要介紹下操作四大組件的常用命令。
pm
pm install demo.apk pm uninstall com.your.pkg pm -l
pm 命令里比較常用的就這幾條了。
前面兩條是安裝和卸載 APK 的命令。
第 3 條是列出當前安裝的所有 APK 包名及其 APK 位置。筆者通常用這條命令配合 grep 來查找某 APK 的安裝信息。
Activity
am start com.chorm.four
am start com.chorm.four/.MainActivity
啟動 APK 。其中第 1 條命令要求主 Activity 的注冊 category 屬性中有 “ android.intent.category.DEFAULT ” 。 第 2 條命令則沒有這個要求,通常用第 2 條命令啟動 APK 比較多。不過還是比較經常出現上面兩條都啟動不了的情況。這個時候就要借助另一條無敵指令來幫忙了。
monkey -p com.chorm.four 1
monkey 據說是一個測試工具,不過不管,筆者只用它來幫忙啟動一些 APK 。monkey -p 是固定參數,后面接個 APK 包名,最后一個數字填個 1 就好了。據說這個工具的設計目的就是想模仿一只猴子,胡亂地去操作我們的 APK ,進而測試 APK 的穩定性等。最后面的數字參數就是想要讓這只猴子胡亂操作的次數。
Broadcast
am broadcast -a my.broadcast.action
通過命令發送一條全局廣播。 -a 參數后接的是廣播 Action 名。
Service
am startservice com.chorm.four/.MyService
通過串口啟動 Service 。
ContentProvider
content query --uri content://stbconfig/authentication content insert --uri content://settings/global --bind name:s:chormname --bind value:s:lemontea content update --uri content://settings/global --bind value:s:hello_xiao_tea --where "name='chormname'" content delete --uri content://settings/global --where "name='chormname'"
ContentProvider 的 CRUD 命令全在這了。其實沒什么,記住這些命令就好了,實在記不住,在串口敲一下 content 命令就會出來簡明幫助信息了。
這里可以關注一下上面標紅的字體。三段式結構是固定的。因為 ContentProvider 是以 key-value 對的方式存儲數據的, name 就代表 key 了,第 2 段 s 表示我們以字符串的形式來匹配字段。 后面的 value:s:xx 也一樣了。 中間的 s 字段還有其它幾種類型,可選的類型有如下幾種
b - boolean, s - string, i - integer, l - long, f - float, d - double
其實這些東西,在串口上敲一下 content 命令都會出來幫助信息。
3、Git
筆者在公司使用的代碼管理工具一直都是 Git ,而且筆者認為 Git 比 SVN 更有優勢。
建倉
git config --global user.name your.name git config --global user.email you@email.com
在首次使用 Git 工具時,需要先設置一下這些信息才能正常使用 Git 的功能。
git init
初始化代碼倉庫,在當前目錄下初始化一個 .git 目錄,並開始跟蹤當前目錄及其子目錄。
git remote add origin git@192.168... git remote -v
第 1 條是為當前 Git 添加一個遠程倉庫。第 2 條則是查看當前 Git 倉庫的遠程倉庫信息。
git push -u origin master
在添加好遠程倉庫信息后,即可以將本地倉庫推送到遠程倉庫了。
不過一般而言,建倉流程都是首先建立遠程代碼倉庫,然后再由我們的機器主動去克隆代碼的。
git clone git@192.168... git clone git@192.168... -b master2 git clone git@192.168... -b master2 myfolder/ git clone --depth 3 git@192.168... -b master2 myfolder/
將遠程倉庫中的代碼克隆到本地來。
第 1 條是默認克隆,完整克隆代碼倉庫,並切換到 master 分支。
第 2 條也是完整克隆,只不過克隆完后會自動切換到指定的 master2 分支。
第 3 條和第 2 條一樣,只是會克隆到指定的目錄中去。
第 4 條是部分克隆,它只會克隆指定的 master2 分支到指定的 myfolder 目錄,並且只會克隆最新 3 條記錄。這種克隆方式對於一些龐大的代碼倉庫來講,能大大減少空間占用量,因為它只克隆最近的幾條記錄,並且這種克隆方式不支持分支切換,所以必須要在克隆前就指定好你想要哪個分支。
其實在工作過程中,建倉這種事,我們軟件開發很少去操心的。
代碼管理
git status
git status vendor/
與當前機器上最新的版本對比,列出有修改的文件。第 1 條命令是列出整個 Git 倉庫的變化。第 2 條命令則是只看指定的 vendor 目錄的變化文件。
git diff xxx.xxx
查看指定的文件的詳細變化情況,可以接多個文件參數。
git add file.name git add .
添加有修改的文件到待提交區。第 1 條命令是添加指定的文件。第 2 條指令是添加所有有變化的文件到待提交區。
git commit -m "Some description"
將待提交區的代碼提交上去,並以 -m 參數后的內容作為描述內容生成一條新的 Git 記錄。
git push
將當前新提交的 Git 修改記錄更新到遠程倉庫中去。
git pull
git pull origin branch2
從遠程代碼倉庫中下載新記錄。第 1 條是更新所有分支。第 2 條則是從 origin 源中更新指定的分支。
git log
git reflog
git log --graph
git log -1
git log --stat
查看提交記錄。
第 1 條是按時間倒序查看所有提交記錄,是最常用的 log 命令。
第 2 條則是查看在本機中的所有操作記錄。
第 3 條可以以圖形的形式查看所有人對分支的提交 / 合並情況。用的比較少。
第 4 條查看最近 1 條提交記錄。
第 5 條查看每條記錄都修改了哪些文件。
git rm file.name
取消跟蹤指定的 file.name 文件。
git clean -df
強制刪除所有未跟蹤且未在忽略列表中的文件。
代碼控制
git reset --hard HAED
git reset file.name
git reset 要回退的版本號 file.name
git reset --hard 版本號
第 1 條命令,強制讓代碼恢復到當前最新記錄。該操作會放棄所有對文件的修改。
第 2 條命令通常用於已經將某文件提交到 “待提交區” 的情況,對這種情況的文件執行這條命令,會使指定的文件回退到 “已修改” 的狀態。
第 3 條命令則是對 “已提交” 的文件進行回退,回退到指定的版本。這種情況其實是新生成一條記錄提交上去。
第 4 條命令是強制讓代碼整體回退到指定的版本號記錄上。
git checkout file.name
將指定文件的修改回退到未修改前的狀態。這條命令只對已發生修改,但尚未添加到 “待提交區” 的文件有效。
分支操作
git remote rm origin branch1
刪除遠程倉庫上的指定的 branch1 分支。
git branch git branch -a git branch branch0
查看分支情況。
第 1 條是查看本地已有的分支情況。
第 2 條是查看本地及遠程倉庫中所有的分支情況。
第 3 條是在本地新建一條分支 branch0 。
git checkout branch2
git checkout -b branch3
切換分支。
第 1 條是切換到指定的 branch2 分支。
第 2 條是新建分支 branch3 並切換過去。
git cherry-pick 記錄版本號
將指定版本號的記錄修改合並到當前分支來。
刪除一條已存在分支的實例
假設我們要刪除一條已有記錄的分支,可以按如下步驟來做。
1. 首先找到這條要刪除的分支名稱;
git branch
2. 刪除這條分支在本地的記錄;
git branch --delete branch_name
3. 刪除在本地保存的遠程分支信息;
git branch -r --delete origin/branch_name
4. 刪除在遠程服務器上的分支信息;
git push origin --delete branch_name
當然,在一般的工作過程中,分支信息是只能增不能刪的。
其它
git config --add core.filemode false
執行這條配置信息后,會使我們本地的 Git 忽略掉文件模式的變化。
git config --global core.quotepath false
解決中文亂碼的問題。
git config --global core.autocrlf false
解決 Windows 與 Linux 系統換行符不同的問題,是否會自動將這些不同的換行符作轉換。
git config --global http.proxy="http://192.168.100.252:38098"
設置網絡代理。
忽略已跟蹤文件的后續修改
在工作過程中,經常會碰到這樣的一種需求:某些文件是必須要提交到 Git 去管理的,但這些文件可能會在工作過程中被自動修改,而我們又不想將這些修改提交上去。所以我們可以這樣做
git update-index --assume-unchanged file.name git update-index --no-assume-unchanged file.name
這兩條命令分別是對 file.name 文件的忽略跟蹤后續修改以及恢復跟蹤后續修改。
如果想看看當前有哪些文件是被忽略跟蹤后續修改的,可以用下面這條命令
git ls-files -v
git grep "xxx"
對了,有時候我們可能需要 grep 整個大包目錄,為了減少一些 grep 工作量,可以用這條命令來代替。效果是一樣的。
