Termux 与 Linux 的区别
Termux 中的环境设置类似于现代Linux发行版在Android上运行,但是有几点重要的区别。
Termux 不符合 FHS 标准
这也是为什么不能直接使用官方Debian或Ubuntu包的原因之一。
Termux不像大部分Linux发行版那样遵循文件结构标准。像是,/bin, /etc, /usr, /tmp和其他常见目录在Termux中是不可用的。因此,所有的程序都必须做一定的修改然后重新编译以符合Termux的运行环境,否则有可能出现找不到配置文件或者数据文件导致的各种错误。
在运行脚本时,可能会出现由释伴(即shebang,例如 #!/bin/sh)导致的问题。为此,Termux提供了一个 termux-fix-shebang
脚本,运行这个脚本可以自动修改脚本的释伴(shebang)部分。新版本的Termux特别提供了一个 termux-exec
包,以允许使用标准的释伴(shebang)。
大部分的包都依赖 $PREFIX/lib 下的一些共享库。Android 7 之前,Termux 链接器通过 $LD_LIBRARY_PATH 来得到共享库的路径。在Android 7 和以后的版本,Termux 使用ELF文件头参数 DT_RUNPATH 来代替 LD_LIBRARY_PATH 。
如果确实需要一个Linux的文件系统结构,可以使用 proot 保中的 termux-chroot 命令:
$ pkg install proot
$ termux-chroot
$ ls /usr
bin doc etc include lib libexec share tmp var
Termux 使用 Bionic libc
为了得到对Android系统的最佳兼容性,Termux下所有的包都是通过 Android NDK 编译的。生成的文件依赖于 Bionic libc (/system/lib或/system/lib64 下的 libc.so, libm.so, libdl.so )。
因为使用了Android提供的libc,并且不遵循文件系统结构标准,导致不能运行直接从Linux发行版中复制出来的包:
- 动态链接的程序不能运行,因为 /lib 目录不存在并且 libc ABI 不匹配。
- 需要联网的静态链接的程序不能正常解析DNS,因为GNU libc 默认不允许静态链接解析器。同时 /etc/resolv.conf 文件也并不存在。
- 在没有root过的 Android 8 和之后的版本上,由于seccomp过滤器的问题。静态链接的程序无法运行。
以上所有这些问题都可以通过PRoot安装一个Linux发行版的rootfs来绕过。
根文件系统是作为普通应用程序的数据存在的
根文件系统和home目录都是存放在/data分区私有的应用程序数据目录中的。 $PREFIX 和 $HOME 环境变量分别指向这些目录。
不可以手动更改 $PREFIX 指向的目录,因为所有的程序都默认为 $PREFIX 是不会改变的。另外,$PREFIX下的二进制文件、符号链接和其他文件不能放到SD卡上,因为SD卡的文件系统不支持unix权限、符号链接、sockets文件,等等。
如果卸载或者清空Termux的数据, $PREFIX 和 $HOME 指向的目录也会被擦除,卸载或清除数据之前要确保重要数据的备份。
Termux 是单用户的
Android 应用都是在沙盒中运行的,每个应用都有自己的Linux用户id和SELinux标签。Termux也不例外,Termux中的所有程序都使用和Termux同样的用户id运行,用户id也许是 u0_a231
这种格式,并且不能更改。
所有的包(除了必须Root才能用的包),都被去掉了 多用户,setuid/getuid和其它类似的功能。同时 ftpd, httpd 和 sshd 的默认端口也分别被修改为 8021, 8080 和 8022 。
由于可以对$PREFIX下的程序组件自由读写,因此要特别注意防止意外覆盖或删除$PREFIX下的文件。