Ubuntu如何搜索命令所对应的二进制包?

本文介绍在Ubuntu和Debian等Linux系统中如何解决命令未找到的问题,通过使用command-not-found工具推荐安装缺失的二进制包,深入探讨如何利用apt-file精确查找命令所在包,适用于Ubuntu、Debian及Kali等系统。
博文背景

如果一个命令在本地不存在,那么该知道它的归属并安装它的二进制包?

具体操作

在Ubuntu下默认应该是会有command-not-found的功能的,如果没有这个功能就用apt安装一下这个工具再exec bash,这个工具能够在命令不存在时给你推荐该安装哪个二进制包,我记得有些精简版的Ubuntu系统比如docker还有lxc应该是没有安装这个玩意的需要手动安装一下,debian和kali默认应该也不具备这个功能,需要手动安装。

但是这个command-not-found用的本质又是apt里面的什么呢?本着溯源的精神我又探究了一波,读者应该使用sudo apt install apt-file来安装apt-file然后update源,这样就可以使用这个来搜索想要的命令,但是一般情况下的搜索会很难找到你想要的东西因为不是根据命令精准匹配,这时候需要一定的搜索技巧,比如搜索java和ping,一般情况下直接执行的命令都是在PATH里面的某个bin目录下,所以我们搜索时带上bin目录,但是搜索java可能会出现javac搜索ping可能会出现ping6之类的造成干扰,这时候就需要使用grep来过滤了以java结尾就可以了,搜索出来的结果基本和command-not-found给出的结果应该是一致的,下面给出两个示范:

(base) ubuntu@debian:~$ java

Command 'java' not found, but can be installed with:

sudo apt install default-jre            
sudo apt install openjdk-11-jre-headless
sudo apt install openjdk-8-jre-headless 

(base) ubuntu@debian:~$ apt-file search /bin/java | grep /bin/java$
openjdk-11-jre-headless: /usr/lib/jvm/java-11-openjdk-amd64/bin/java
openjdk-8-jre-headless: /usr/lib/jvm/java-8-openjdk-amd64/bin/java
openjdk-8-jre-headless: /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java

这里的转义字符可能要注意具体我没仔细研究还有个叫apt-cache的东西可能也可以搜索有兴趣的读者自己尝试一下。

<think>我们正在为Android9设备编译一个兼容的su二进制文件。目标是在刷机固件中集成后能够正常使用。编译su二进制文件通常有两种主流方式:1.使用AOSP(AndroidOpenSourceProject)源码环境编译,利用系统自带的su模块(但默认不编译,需要配置)2.使用第三方项目如Magisk或SuperSU的源码编译由于用户提到是安卓9(Pie),我们这里主要采用AOSP方式,因为AOSP的su模块相对稳定且与系统兼容性好。步骤:1.**准备AOSP环境**-下载Android9的源码(具体版本号如:android-9.0.0_rXX)-配置编译环境(Ubuntu系统推荐,安装必要的)2.**配置AOSP以含su**-AOSP中有一个`su`模块,位于`system/extras/su/`目录下,但默认不会被编译。我们需要修改编译配置使其被含。3.**修改编译配置**-在AOSP根目录下,打开`build/target/product/core.mk`文件(或者根据你的产品配置,可能是其他mk文件)-在`PRODUCT_PACKAGES`列表中添加`su`,例如:```makefilePRODUCT_PACKAGES+=\...\su```-另外,为了将su安装到系统分区,我们还需要确保有足够的权限。在Android9中,系统分区是只读的,所以我们需要在刷机中预置。4.**针对su模块的权限设置**-在`system/extras/su/`目录下,有一个`Android.mk`文件,我们可以在这里修改su的安装路径和权限。-默认情况下,它会安装到`/system/xbin/su`,并且权限是`4750`(即root所有,root组可执行,并且设置SUID)。但为了确保所有用户都能使用,我们可能需要修改权限为`4755`(即所有用户可执行)。-修改`Android.mk`(在`system/extras/su/`目录下):```makefile#在Android.mk中找到设置权限的地方,通常是:include$(BUILD_EXECUTABLE)#在这之前,我们可以设置LOCAL_POST_INSTALL_CMD来修改权限LOCAL_POST_INSTALL_CMD:=$(hide)chmod4755$(TARGET_OUT)/xbin/su```或者,如果原本没有设置权限,我们可以通过修改`Android.mk`中的`LOCAL_MODULE_PATH`和`LOCAL_MODULE_TAGS`等确保安装到系统分区,并在安装后设置权限。5.**编译su**-在AOSP根目录下执行:```bashsourcebuild/envsetup.shlunch<your_target>#选择你的设备目标,例如aosp_arm-engmakesu```-编译完成后,生成的su二进制文件位于:`out/target/product/<your_target>/system/xbin/su`6.**验证su二进制文件**-使用`file`命令检查架构是否匹配目标设备(如arm,arm64等)-使用`adbpush`将其推送到设备的`/system/xbin/`目录下(需要系统分区可写,或者通过刷机集成)-设置权限:`chmod4755/system/xbin/su`,并设置所有者`chown0.0/system/xbin/su`-测试执行:`su-cid`,应返回root权限。7.**处理SELinux问题**-在Android9中,即使su二进制文件正确,SELinux也可能会阻止其运行。因此,我们需要为su添加SELinux规则。-在设备上临时禁用SELinux:`setenforce0`,测试su是否工作。如果工作,则需要在编译时添加SELinux策略。-在AOSP中,我们可以修改sepolicy,添加以下内容(具体位置可能在`system/sepolicy`目录中):-在`system/sepolicy/public/domain.te`中添加:```teallowshellsu:processtransition;```-或者更完整的策略(根据实际情况调整):```te#允许从shell域转换到su域allowshellsu_exec:file{executegetattropenreadexecute_no_trans};allowshellsu:processtransition;allowsushell:fduse;allowsushell:fifo_file{readwrite};#允许su域执行特权操作allowsukernel:system{syslog_modsyslog_console};allowsuself:capability{dac_overridedac_read_searchsetgidsetuid};allowsuself:process{setpgidsetrlimit};```-重新编译整个系统(或sepolicy模块)以含这些策略。8.**集成到刷机**-将编译好的su二进制文件放入刷机(ROM)的`system/xbin/`目录。-在刷机的安装脚本(如updater-script)中设置权限:```textset_perm(0,0,06755,"/system/xbin/su");```-同时,确保刷机含了修改后的sepolicy(如果有修改)。9.**替代方案:使用Magisk**-如果上述过程复杂,且用户接受Magisk方案,可以直接使用Magisk的boot.img修补功能。Magisk提供了完整的root解决方案,括su二进制文件和SELinux策略处理。注意:由于Android9的SELinux策略较为严格,手动编译的su可能仍然面临策略问题。因此,使用成熟的Magisk方案可能更为简单可靠。如果用户坚持自己编译,那么按照上述步骤操作,但需要根据具体设备调整策略。相关问题:1.如何为Android9设备下载对应的AOSP源码?2.如何解决编译su时遇到的SELinux策略问题?3.Magisk如何集成到自定义ROM中?4.如何验证编译的su二进制文件是否与设备架构兼容?5.在Android9上,系统分区只读,如何永久修改系统分区以集成su?</think>### 如何为 Android 9 编译兼容的 su 二进制文件 #### 核心原理 Android 9 的 su 二进制文件需要满足: 1. **架构兼容性**:匹配设备 CPU 架构(arm/arm64/x86) 2. **权限控制**:含 SUID 位和 SELinux 策略 3. **启动机制**:与 init 系统集成 4. **系统签名**:通过平台密钥签名(非 AOSP 编译需自行签名) --- ### 详细编译步骤 #### 1. 准备编译环境 ```bash # 安装基础依赖(Ubuntu 示例) sudo apt update sudo apt install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev libgl1-mesa-dev libxml2-utils xsltproc unzip python openjdk-8-jdk # 配置 Repo 工具 mkdir ~/bin curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo ``` #### 2. 获取 AOSP 源码 ```bash # 创建源码目录 mkdir aosp_android-9 && cd aosp_android-9 # 初始化仓库(使用 Android 9.0.0 版本) repo init -u https://android.googlesource.com/platform/manifest -b android-9.0.0_r75 # 同步代码(约 40GB) repo sync -j8 --no-tags ``` #### 3. 修改编译配置 编辑 `system/extras/su/Android.mk`: ```makefile LOCAL_MODULE := su LOCAL_SRC_FILES := su.c LOCAL_CFLAGS := -DALLOW_SU_ROOT=1 # 允许 root 访问 LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := EXECUTABLES include $(BUILD_EXECUTABLE) ``` #### 4. 添加 SELinux 策略 在 `system/sepolicy/public/domain.te` 末尾添加: ```te # 允许 su 域转换 type_transition shell su_exec:process su; allow shell su_exec:file { execute getattr open read }; ``` #### 5. 编译 su 二进制 ```bash # 初始化编译环境 source build/envsetup.sh # 选择目标设备架构(示例:arm64) lunch aosp_arm64-eng # 单独编译 su 模块 make su -j$(nproc) ``` #### 6. 验证和签名 ```bash # 检查生成文件 file out/target/product/generic_arm64/system/bin/su # 应显示: ELF 64-bit LSB shared object, ARM aarch64... # 设置权限(SUID) chmod 6755 out/target/product/generic_arm64/system/bin/su # 平台签名(使用 AOSP 测试密钥) ./development/tools/make_key testkey '/CN=Android' signapk -w platform.x509.pem platform.pk8 out/target/product/generic_arm64/system/bin/su su-signed ``` #### 7. 集成到刷机 将签名的 su 文件放入刷机的 `system/bin/` 或 `system/xbin/` 目录,在 `META-INF/com/google/android/updater-script` 中添加: ```bash # 设置权限和所有者 set_perm(0, 0, 06755, "/system/xbin/su"); ``` #### 8. 刷机后验证 ```bash adb shell su -c id # 应返回 uid=0(root) ``` --- ### 关键注意事项 1. **架构匹配**: - ARM 设备:`lunch aosp_arm-eng` - ARM64 设备:`lunch aosp_arm64-eng` - x86 设备:`lunch aosp_x86-eng` 2. **SELinux 处理**: ```bash # 临时禁用测试 adb shell setenforce 0 ``` 若生效需永久添加策略到 `sepolicy` 文件 3. **签名要求**: - 非 AOSP 官方编译需替换 `platform.x509.pem` 和 `platform.pk8` - 可复用设备原厂 ROM 的签名密钥 4. **替代方案**: 使用 Magisk 的 `libsu` 项目编译: ```bash git clone https://github.com/topjohnwu/libsu cd libsu/core ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk ``` --- ### 常见问题解决 | 问题现象 | 解决方案 | |---------|---------| | `su: permission denied` | 检查 SUID 位 (`chmod 6755`) 和 SELinux 策略 | | `su: not found` | 确保路径在 `$PATH` 中(`/system/bin`或`/system/xbin`) | | 刷机后消失 | 检查 ROM 的 dm-verity 和 AVB 是否移除 | | 无限重启 | 检查 SELinux 策略冲突,使用 `adb logcat | grep avc` | > 建议优先使用 Magisk 方案[^1],其通过修补 `boot.img` 实现免签名集成,自动处理 SELinux 兼容问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值