誰會在手機跑shell script呀?
解釋如何在最新Android系統安裝BusyBox。
BusyBox是一款行之有年的自由軟體,使用GPL授權釋出。根據官網資料,BusyBox透過單一的二進位執行檔,將常用的Unix-like系統工具打包進去,這個執行檔是靜態連結的,不依賴外部函式庫就能用。
舉例來說,一個busybox的指令,才不到2MB而已,就包含了ash shell、vi文字編輯器、wget下載器、httpd伺服器、tar解壓縮、chroot容器、mv、cp、rm、diff、ping……等實用命令行工具,可說是一個便利工具箱。

BusyBox是輕量可移植的,支援多種處理器架構,常用於嵌入式系統,當然也能用在Android囉。
Android是基於Linux核心開發的系統,但幾乎沒有使用Linux發行版常用的GNU coreutils,缺少很多Linux的命令行工具。GNU coreutils動輒20MB以上,要移植這些工具到Android也顯得太龐雜了些。Android頂多只有使用Toybox,在Android 6.0之後加入。Toybox比BusyBox還要精簡,而且它的BSD授權條款更為寬鬆,方便商業公司利用而不會產生GPL授權汙染的問題。但是,Toybox功能依然不如BusyBox完整。
透過安裝BusyBox,便可以做到GNU coreutils的七八成功能,又不會佔用太多空間。
通常需要Root權限,才可以在Android安裝BusyBox。
我們可以用Busybox在Android上建立含有Linux userspace的chroot環境。此外一些APP在操作系統檔案的時候也會用到BusyBox。
Android 7.0以前的大Root時代,都會在Android安裝Busybox這個軟體,補足缺少的Linux工具,可是隨著Android框架成熟,現在很少APP會去用這些底層指令了,即使是有Root的也一樣吧。大概只有做Linux chroot或者備份檔案會用到了吧。
1. Android安裝BusyBox的方案#
方案1:使用Root管理器內建的#
如果你的Root方案是Magisk或KernelSU或APatch,他們就有內建BusyBox了,無需額外安裝模組。因為SELinux限制與OTA更新考量,Busybox不會硬塞到系統目錄了,都是透過overlay掛載。
Magisk的Busybox絕對路徑位於/data/adb/magisk/busybox
KernelSU位於/data/adb/ksu/bin/busybox
APatch位於/data/adb/ap/bin/busybox
方案2:手動刷入BusyBox模組#
舊版Magisk或SuperSU用戶需要手動刷Busybox模組。
雖然BusyBox官網有提供靜態連結的二進位檔可以直接在Android shell執行,你不應該修改Android的/system/bin/來安裝Busybox,而是採取systemless的方式安裝。
有很多BusyBox的安裝器出現,目前能用的是BuiltIn-BusyBox與Busybox NDK。
更舊的Android系統才會透過SuperSU強行把BusyBox二進位檔塞到系統目錄。
2. 如何使用BusyBox指令#
若要操作BusyBox指令,你需要終端機模擬器,例如Termux
授予Root權限之後,切換到su
su- 便可以在Android shell喚出BusyBox了
busybox --help- 如果顯示inaccesible or not found找不到BusyBox,嘗試輸入
/data/adb/下的絕對路徑:
/data/adb/magisk/busybox --help- 有些版本的Busybox是透過符號連結提供二進位檔的,它可能會在
/system/bin/建立符號連結指向busybox,如果你要使用一個指令,可以直接呼叫,例如輸入vi就能執行busybox vi。不過,現在的Android含有Toybox,所以Busybox就不會建立符號連結了。
最安全的方法,是在指令加上busybox前綴,才能確認你呼叫的是BusyBox提供的工具而非Toybox的版本:
busybox vi- 另外,你也可以在電腦的ADB使用BusyBox指令。
adb root
adb shell busybox --help3. 利用BusyBox建立Linux chroot環境#
BusyBox提供的工具畢竟還是太精簡了,如果需要更複雜的工具,就建立一個chroot環境,使用Linux發行版的userspace套件吧。
4. 附錄:免Root安裝BusyBox#
Termux有收錄BusyBox套件:
pkg install busybox不過Termux本身就夠多命令行工具了,不太需要用到BusyBox。


