安卓手机上安装termux,把手机当linux服务器用

旧的安卓手机不要扔,可以拿来做一个微型的linux服务器,编程开发,跑服务都不在话下!本文就以6年前发布的小米2s为例,亲自带大家一起体验一下这种手机服务器

一、升级最新安卓操作系统

像小米2s这样已经发布6年多的手机,配置已经不够用了。但是我们知道,谷歌每年发布的新安卓系统版本都有性能的优化,所以旧手机如果能升级系统,自然也能改善性能。工欲善其事必先利其器,我们先把旧手机升级一把再说。

魔趣ROM介绍

在这里插入图片描述
这是一个国内团队维护ROM,开源并且支持多款安卓设备。最主要的是他跟随谷歌的脚步,当有新的安卓版本发行后,魔趣ROM很快就能为多款安卓设备适配。

魔趣ROM下载地址:https://download.mokeedev.com/
需要的朋友可根据自己的手机型号选择下载并刷机使用。
例如我的小米2s手机,选品牌和型号
在这里插入图片描述

选安卓的版本,我选的是8.1版本:
在这里插入图片描述

怎么刷机不是我们关注的重点,需要的请到魔趣论坛或百度搜索。刷机后,我那6年前的破手机用上了androd 8.1:
在这里插入图片描述
极力推荐!!!!!
魔趣ROM的是开源的,这意味着:只要我们愿意,可以和小米的android系统工程师一样,随时可以下载代码下来定制自己的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表现形式是一个apk,这个apk的提供了一个shell终端界面(据说也可以支持linux图形界面)。

termux的安装与使用

软件下载地址

https://f-droid.org/packages/com.termux/

软件界面

软件安装后,在手机上展现的界面如下所示,与我们平时操作的linux终端长得一样:

在这里插入图片描述

安装openssh,并从PC端访问

终端界面在手机上操作不方便,所以我们安装一个ssh服务,然后用PC来操作它。

  1. 更新软件源
apt update
  1. 安装openssh-server
pkg install openssh
  1. 给termux对应的用户设置一个密码
$passwd

#根据提示设置一个密码
New password:
  1. 安装后,需要手动启动sshd
sshd &

注意:termux的ssh服务默认端口为8022

  1. 测试连接

在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"

我们就可以看到如下端倪:

  1. 当前shell其实为/data/data/com.termux/files/usr/bin/bash
  2. 当前用户为u0_a79,与安卓系统给termux apk的uid一致。
  3. LD_LIBRARY_PATH为/data/data/com.termux/files/usr/lib,当前shell执行的程序链接的是termux自己的库文件,与安卓系统/system/lib下的无关。
  4. LD_PRELOAD加入了一个libtermux-exec.so,说明**应该termux hook了一些系统API接口**。
  5. PATH环境变量不包含/system/bin目录,所有命令都与android系统自带的命令了无关,termux的shell是一个独立的shell环境。
  6. HOME目录为/data/data/com.termux/files/home

通过ps命令,我们就可以清楚的知道,它其实是termux fork出来的一个子进程:

  $ 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等语言在这个微型服务器里都正常运行

如何打造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那么方便但起码可用。

1558510920356

更优雅的写代码姿势

目前在vs code编辑器里,微软准备发行远程编辑代码的插件,目前在预览版本里测试,正式版还需等待。有了这个功能后,我们的这个linux服务器,在windows端编辑代码后立即就能同步过去,非常好用了。
在这里插入图片描述

在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了。

  1. 我们并没有以root身份运行

通过shell界面我们看到,我们似乎在以root权限运行,但是其实是模拟出来的,所以你别想写个内核模块安装到真正的内核里边去。

  1. 在ubuntu中,运行sshd, samba都失败了

    sshd进程一运行就没了,通过gdb运行我们发现它其实段错误了:

在这里插入图片描述

同样,smbd进程也奔溃了,报了一个无权限bind socket的错误。

​ 经过测试,似乎这种chroot后的系统没有termux的稳定,建议使用用termux。对于已经root的系统,可能不需要proot,也许兼容性会更好,感兴趣的可以自行进行尝试。

  1. 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芯片的性能的不断提升,完全可以把你的手机当成一个随身linux服务器,推荐喜爱技术的朋友去尝试一下。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/yinmingxuan/article/details/90511558