安卓手機上安裝termux,把手機當linux伺服器用
舊的安卓手機不要扔,可以拿來做一個微型的linux伺服器,編程開發,跑服務都不在話下!本文就以6年前發布的小米2s為例,親自帶大家一起體驗一下這種手機伺服器並簡單分析其中的一些原理。
一、升級最新安卓操作系統
像小米2s這樣已經發布6年多的手機,配置已經不夠用了。但是我們知道,谷歌每年發布的新安卓系統版本都有性能的優化,所以舊手機如果能升級系統,自然也能改善性能。工欲善其事必先利其器,我們先把舊手機升級一把再說。
魔趣ROM介紹
這是一個國內團隊維護ROM,開源並且支持多款安卓設備。最主要的是他跟隨谷歌的腳步,當有新的安卓版本發行後,魔趣ROM很快就能為多款安卓設備適配。
魔趣ROM下載地址:https://download.mokeedev.com/,需要的朋友可根據自己的手機型號選擇下載並刷機使用。
例如我的小米2s手機,選品牌和型號
選安卓的版本,我選的是8.1版本:
怎麼刷機不是我們關注的重點,需要的請到魔趣論壇或百度搜索。刷機後,我那6年前的破手機用上了androd 8.1:
魔趣ROM的是開源的,這意味著:只要我們願意,隨時可以下載代碼下來定製自己的ROM,這非常符合開發人員的胃口!
二、將安卓手機打造成linux伺服器
理解linux與安卓的關係
- 首先,安卓操作系統的內核是基於linux的,谷歌為安卓系統做了特殊的定製,如增加了binder驅動,適合手機的電源管理驅動,Low Memory Killer驅動等等。
- 其次,安卓系統和普通的linux的libc庫不一樣,可執行程序需要專門的android編譯器(arm-linux-androideabi-gcc/g++)編譯,用專門的鏈接器(arm-linux-androideabi-ld)鏈接專用於安卓的libc.so才能運行。
為什麼我們只關注C/C++,不是有那麼多語言編寫的程序嗎?
因為c/c++是基礎,離開它們基本沒什麼能跑的了。java虛擬機是c++編寫的,python的解析器是c寫的,js的解析執行引擎也是c/c++寫的。。。
本文的主角---termux簡介
termux 是一個安卓平台下的app, 它能夠在安卓上實現一個微型的linux,具有命令行界面,可以以apt方式簡單的安裝各種軟體。
termux的安裝與使用
軟體下載地址
https://f-droid.org/packages/com.termux/
軟體界面
軟體安裝後,在手機上展現的界面如下所示,與我們平時操作的linux終端長得一樣:
安裝openssh,並從PC端訪問
終端界面在手機上操作不方便,所以我們安裝一個ssh服務,然後用PC來操作它。
1.更新軟體源:
apt update
2.安裝openssh-server:
1pkg install openssh
3.給termux對應的用戶設置一個密碼:
$passwd
#根據提示設置一個密碼
New password:
4.安裝後,需要手動啟動sshd:
sshd &
注意:termux的ssh服務默認埠為8022
5.測試連接
在PC端,我在windows上用secure crt連接手機的sshd,設置埠為8022,連接似成功的。連接成功後,你就真正擁有一個微型的linux伺服器,可以將手機息屏,為所欲為啦。
termux的簡單分析
termux在android系統中運行,與普通的app沒有什麼兩樣,在apk安裝時,系統為其分配一個用戶,例如我的分配的用戶為u0_a79。我在手機上點擊termux這個app後,其實termux會以u0_a79這個用戶身份創建一個新的bash進程,然後所有的命令都在這個bash進程里解析執行。
在termux的界面輸入export命令,結果如下:
$ export
declare -x ANDROID_DATA="/data"
declare -x ANDROID_ROOT="/system"
declare -x EXTERNAL_STORAGE="/sdcard"
declare -x HOME="/data/data/com.termux/files/home"
declare -x LANG="en_US.UTF-8"
declare -x LD_LIBRARY_PATH="/data/data/com.termux/files/usr/lib"
declare -x LD_PRELOAD="/data/data/com.termux/files/usr/lib/libtermux-exec.so"
declare -x LOGNAME="u0_a79"
declare -x OLDPWD
declare -x PATH="/data/data/com.termux/files/usr/bin:/data/data/com.termux/files/usr/bin/applets"
declare -x PREFIX="/data/data/com.termux/files/usr"
declare -x PWD="/data/data/com.termux/files/home"
declare -x SHELL="/data/data/com.termux/files/usr/bin/bash"
declare -x SHLVL="1"
declare -x TERM="vt100"
declare -x USER="u0_a79"
我們就可以看到如下端倪:
- 當前shell其實為
- /data/data/com.termux/files/usr/bin/bash
- 當前用戶為u0_a79,與安卓系統給termux 分配的的uid一致。
- LD_LIBRARY_PATH為
- /data/data/com.termux/files/usr/lib,當前shell執行的程序鏈接的是termux自己的庫文件,與安卓系統/system/lib下的無關。
- LD_PRELOAD加入了一個libtermux-exec.so,說明應該termux hook了一些系統API介面。
- PATH環境變數不包含/system/bin目錄,所有命令都與android系統自帶的命令了無關,termux的shell是一個獨立的shell環境。
- termux shell里也有am等android命令,但是它自帶的,與用/system/bin下的am無關。
- HOME目錄為
- /data/data/com.termux/files/home
通過ps命令,我們就可以更清楚的知道,它其實是termux 創建的一個子進程:
```shell
$ ps
PID USER TIME COMMAND
29893 u0_a79 0:00 /data/data/com.termux/files/usr/bin/bash -l
```
因此我們可以確定:
termux的shell是與/system/bin/下的程序一樣,用的都是android的libc,編譯器應該是arm-linux-androideabi-gcc/g++。
三、玩termux
打造個人編程環境
我們已經擁有一個微型linux伺服器了,現在我們嘗試在裡邊編程開發。
安裝c/c++編譯器:
apt install clang
測試
$ gcc -v
clang version 8.0.0 (tags/RELEASE_800/final)
Target: arm-unknown-linux-android
Thread model: posix
InstalledDir: /data/data/com.termux/files/usr/bin
可以看到列印的arm-unknown-linux-android,的確就是android的編譯器。經過測試,用這個編譯器編譯的程序是可以直接放到android shell中執行的。
經過測試,c、c++、python、node.js等語言在這個微型伺服器里都正常運行;搭建tomcat之類的服務也沒問題。
如何打造java編程環境?
從前面的分析我們知道,termux shell和android shell一樣,執行java位元組碼的是ART虛擬機,而不是普通的java虛擬機,所以javac編譯的.class是無法運行的。
如果一定要執行java位元組碼,需要通過dx工具將位元組碼轉換成dex文件,然後art虛擬機才能執行。
#termux下不能用openjdk,可以用ecj
apt install ecj
#adroid的.class轉.dex工具
apt install dx
apt install termux-tools
#編譯
ecj HelloWorld.java
dx --dex --output=HelloWorld.dex HelloWorld.class
#執行
#參照/system/bin/pm 的內容執行即可
很多人肯定會說,這個java環境不爽。那麼想打造一個像普通伺服器那樣的java環境怎麼做呢,可以「安裝」一個操作系統,後邊會介紹。
如何在PC與termux之間傳輸文件?
我們在伺服器內寫代碼,都在/data/data/com.termux/files/home這個目錄里,手機沒有root的話,我們是無法訪問這個目錄的。 我本來想安裝一個samba伺服器,發現沒有這個軟體包,所以只能藉助網路傳輸文件:
通過scp工具(windows下用winscp)傳輸文件,雖然沒有直接用samba那麼方便但起碼可用。
在termux中「安裝」ubuntu
termux的linux環境對很多人來說基本是夠用的,但是依然是一種android定製版linux,與普通嵌入式linux系統還是有差異的,例如沒有普通的java虛擬機。
下面介紹如何在termux shell里搭建一個ubuntu系統環境:
安裝wget
用於下載文件
pkg install wget
安裝proot
在linux中,chroot是一個需要root許可權的操作,它允許將當前根文件系統切換到另外一個目錄。例如手機中的進程對應的根目錄為/, 我們弄一個/data/local/tmp/xxxx文件夾, 裡邊有ubuntu的根文件系統,我們chroot到這個文件夾後,在shell界面里看到的/則切換到/data/local/tmp/xxxx了。我們說的安裝ubuntu其實只是chroot到一個ubuntu的根文件系統文件夾里而已。
proot是一個無需root許可權就能執行chroot操作的工具。用於在ubuntu里模擬需要sudo的許可權(否則沒法安裝軟體)。
pkg install proot
下載atilo腳本
wget https://raw.githubusercontent.com/YadominJinta/atilo/master/atilo
下載ubuntu根文件系統並chroot
chmod +x ./atilo
./atilo install ubuntu
#這個命令會執行proot,chroot到所下載的ubuntu根文件系統
startubuntu
執行startubuntu後,根目變到 --> data/data/com.termux/files/home/.atilo/ubuntu去了, 我們就感覺進入了ubuntu系統了。
我們再來對比一下這個ubuntu shell與termux shell不一樣的地方:
- termux shell里,根目錄與android的是一樣的,你還可以訪問/system, /sdcard目錄等原始android系統目錄
- startubuntu後,就像執行了chroot操作一樣,根目錄都變了,已經看不到/system 這種分區了(除非mount --bind過來)。
簡單分析和測試我們「安裝」的這個ubuntu系統
1.這個系統用的是通用的libc,android系統下的可執行程序無法在這個系統中運行。
我們可以通過查看gcc的版本:
root@localhost:~/workspace# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/8/lto-wrapper
Target: arm-linux-gnueabihf
可見用的是arm-linux-gnueabihf,而不是arm-linux-androideabi了。
2.我們並沒有以root身份運行
通過shell界面我們看到,我們似乎在以root許可權運行,但是其實是模擬出來的,所以你別想寫個內核模塊安裝到真正的內核裡邊去。
3.在ubuntu中,運行sshd, samba都失敗了
sshd進程一運行就沒了,通過gdb運行我們發現它其實段錯誤了:
同樣,smbd進程也奔潰了,報了一個無許可權bind socket的錯誤。
似乎這種chroot後的系統沒有直接用termux穩定。對於已經root的系統,可能不需要proot,也許兼容性會更好,感興趣的可以自行進行嘗試。
4.samba服務沒法用讓我很失望,但其日誌中報的socket bind許可權問題是怎麼回事?
[2019/05/23 01:00:34.679242, 0] ../../source3/lib/util_sock.c:357(open_socket_in)
open_socket_in(): setsockopt: SO_REUSEPORT = true on port 139 failed with error = Protocol not available
[2019/05/23 01:00:34.680860, 0] ../../source3/lib/util_sock.c:396(open_socket_in)
bind failed on port 139 socket_addr = 0.0.0.0.
Error = Permission denied
經過驗證,自己寫一個tcp server運行是沒有問題的,只是不支持SO_REUSEPORT這個套接字選項。但是ubuntu系統中綁定的埠號與實際在android中的埠是不一樣的,具體的埠號需要到外部termux的shell才能看出來。
例如:我在ubuntu shell中寫了一個服務,監聽的是9999埠,而你外部要訪問這個服務時,確要連接3456埠。
四、寫在最後
通過親自體驗,在小米2s上使用termux基本能滿足對一個微型linux伺服器的需求,我甚至想在我的新手機上也弄一個。對於需要用ndk編譯android native可執行程序的人來說,直接在android中編譯程序並立馬可以執行,而不需要每次adb push到機器里,也是非常不錯的體驗。
termux擁有比較完備的軟體源,開發環境支持得很完善,可玩性非常高。隨著arm晶元的性能的不斷提升,運行內存都趕超PC了,完全可以把你的手機當成一個隨身linux伺服器,推薦喜愛技術的朋友去嘗試一下。
歡迎關注我們的同名微信公眾號「麻辣軟硬體」,與我們交流更多技術相關知識!