/bin/sh -c的必要性

博客介绍了向权限受限的文件写入信息时,因重定向符号无root权限导致失败的问题。给出两种解决办法,一是用“sh -c”扩展sudo影响范围,二是用管道和tee命令。还提到在shell脚本中,使用/bin/sh -c可让Java获取所有echo输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、

比如要向 test.asc 文件中随便写入点内容,可以:
$ echo "信息" >> test.csv
如果将 test.asc 权限设置为只有 root 用户才有权限进行写操作:
$ sudo chown root.root test.csv
然后,我们使用 sudo 并配合 echo 命令再次向修改权限之后的 test.asc 文件中写入信息:
$ sudo echo "hahah" >> test.csv
-bash: test.asc: Permission denied
这时可以看到 bash 拒绝这么做,说是权限不够。这是因为重定向符号 “>” 和 ">>" 也是 bash 的命令。我们使用 sudo 只是让 echo 命令具有了 root 权限,但是没有让 “>” 和 ">>" 命令也具有 root 权限,所以 bash 会认为这两个命令都没有像 test.csv文件写入信息的权限。
解决这一问题的途径有两种。

第一种是利用 "sh -c" 命令,它可以让 bash 将一个字串作为完整的命令来执行,这样就可以将 sudo 的影响范围扩展到整条命令。具体用法如下:
$ sudo /bin/sh -c 'echo "hahah" >> test.asc'

另一种方法是利用管道和 tee 命令,该命令可以从标准输入中读入信息并将其写入标准输出或文件中,具体用法如下:
$ echo "hahah" | sudo tee -a test.asc
注意,tee 命令的 "-a" 选项的作用等同于 ">>" 命令,如果去除该选项,那么 tee 命令的作用就等同于 ">" 命令

二、

在一个shell脚本中如果有多个echo命令,如果不适用/bin/sh -c执行脚本,那么在java中使用BufferedReader获取脚本的输出时,只能获取到第一个echo的输出,使用/bin/sh -c则能获取到所有的echo输出。


 

<think>我们遇到了在构建Linux内核模块时出现的错误,特别是与`aarch64-linux-android-gcc`工具链相关的文件未找到问题。错误信息中出现了`/bin/sh:1:-print-file-name=include:notfound`和`/bin/sh:1:-Wp,-MMD,/home/kiki/Desktop/rwProcMem_module/.sys.o.d:notfound`,这表明编译过程中调用编译器时出现了问题。从错误信息看,`make`在尝试调用交叉编译器`aarch64-linux-android-gcc`时失败。可能的原因包括:1.工具链未正确安装或路径配置错误。2.在`make`命令中指定的`CROSS_COMPILE`路径不正确或格式有误。在用户提供的`make`命令中,我们看到:```bashmake-C/home/kiki/Desktop/5.1-common/outM=/home/kiki/Desktop/rwProcMem_moduleARCH=arm64SUBARCH=arm64CROSS_COMPILE=CROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-modules```这里指定了`CROSS_COMPILE`,但是它的值看起来不正确:`CROSS_COMPILE=CROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-`。这实际上将`CROSS_COMPILE`变量设置成了一个包含路径和前缀的字符串,但格式应为`<路径>/<前缀>`,其中前缀是编译器命令的前缀(如`aarch64-linux-android-`),这样编译器命令就会是`<路径>/<前缀>gcc`。注意:通常`CROSS_COMPILE`只需要指定前缀,而工具链的路径通过`PATH`环境变量来指定,或者将路径直接包含在`CROSS_COMPILE`中(即`CROSS_COMPILE`可以是完整路径加前缀)。但是这里我们同时指定了路径和前缀,并且注意在路径末尾有一个`/`,然后前缀是`aarch64-linux-android-`,这样组合后,编译器路径应该是`/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-gcc`。然而,错误信息提示找不到某些命令(如`-print-file-name=include`),这通常是因为编译器没有正确调用。因此,我们需要检查:1.指定的编译器路径是否存在?即`/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-gcc`是否存在?2.该编译器是否具有可执行权限?3.是否安装了必要的32位库(如果在64位系统上运行)?###解决步骤:####1.验证工具链安装检查工具链路径下是否存在`aarch64-linux-android-gcc`:```bashls/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-gcc```如果不存在,可能需要重新安装或下载工具链。####2.检查环境变量在`make`命令中,我们指定了`CROSS_COMPILE`,但也可以考虑通过环境变量设置。另外,确保工具链的`bin`目录在`PATH`环境变量中,这样`make`可以找到编译器。可以尝试将工具链的`bin`目录加入`PATH`,并重新设置`CROSS_COMPILE`为前缀(不含路径):```bashexportPATH=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin:$PATHexportARCH=arm64exportCROSS_COMPILE=aarch64-linux-android-```然后运行`make`命令时不再指定`ARCH`和`CROSS_COMPILE`,因为环境变量已经设置:```bashmake-C/home/kiki/Desktop/5.1-common/outM=/home/kiki/Desktop/rwProcMem_modulemodules```####3.修正make命令中的CROSS_COMPILE如果不想设置环境变量,可以修正`make`命令中的`CROSS_COMPILE`参数。原命令中:```bashCROSS_COMPILE=CROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-```这实际上将`CROSS_COMPILE`变量设置为字符串`CROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-`,这显然是错误的。正确的指定方式应该是:```bashCROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-```注意:这里去掉了多余的`CROSS_COMPILE=`。因此,正确的命令应该是:```bashmake-C/home/kiki/Desktop/5.1-common/outM=/home/kiki/Desktop/rwProcMem_moduleARCH=arm64SUBARCH=arm64CROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-modules```####4.检查依赖库如果工具链是32位的,在64位系统上运行可能需要安装32位库。例如,在Ubuntu上,可以安装:```bashsudoapt-getinstalllib32z1lib32ncurses5lib32stdc++6```####5.检查编译器权限确保工具链中的编译器可执行:```bashchmod-R+x/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin```###示例:正确编译命令假设工具链路径正确,我们可以这样编译:```bash#设置环境变量(推荐)exportARCH=arm64exportCROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-make-C/home/kiki/Desktop/5.1-common/outM=/home/kiki/Desktop/rwProcMem_modulemodules```或者```bash#不设置环境变量,在命令行中指定make-C/home/kiki/Desktop/5.1-common/outM=/home/kiki/Desktop/rwProcMem_moduleARCH=arm64CROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-modules```###总结主要问题在于`make`命令中`CROSS_COMPILE`的指定方式有误,多写了`CROSS_COMPILE=`。修正后应该可以解决编译器未找到的问题。同时,确保工具链安装正确,并具有执行权限。如果问题依旧,请检查工具链是否与目标内核版本兼容,以及内核配置是否正确。</think>### 解决 `aarch64-linux-android-gcc not found` 错误 当构建 Linux 内核模块时遇到 `aarch64-linux-android-gcc not found` 错误,这通常是由于工具链路径配置不正确或环境变量缺失导致的。以下是详细的解决步骤: #### 1. **验证工具链安装路径** 首先确认 Android NDK 工具链是否已正确安装: ```bash ls /home/kiki/aarch64-linux-android-4.9-toolchain-master/bin ``` 检查输出中是否包含 `aarch64-linux-android-gcc` 文件。如果不存在,需要重新下载或安装 Android NDK。 #### 2. **设置环境变量(关键步骤)** 在终端中设置正确的环境变量: ```bash export ARCH=arm64 export CROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android- export PATH=$PATH:/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin ``` #### 3. **修正 make 命令** 修改你的 make 命令,移除非标准的 `CROSS_COMPILE=` 前缀: ```bash make -C /home/kiki/Desktop/5.1-common/out \ M=/home/kiki/Desktop/rwProcMem_module \ ARCH=arm64 \ CROSS_COMPILE=/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android- ``` #### 4. **验证编译器可访问性** 手动测试编译器是否能被调用: ```bash /home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-gcc --version ``` 如果显示 "command not found",尝试添加可执行权限: ```bash chmod +x /home/kiki/aarch64-linux-android-4.9-toolchain-master/bin/aarch64-linux-android-* ``` #### 5. **安装必要的依赖库(针对 CentOS/RHEL)** 参考引用[1],安装编译所需的开发库: ```bash sudo yum install libtool-ltdl-devel gcc-c++ libxml2-devel.aarch64 \ libcurl-devel.aarch64 pcre2-devel.aarch64 json-c-devel.aarch64 ``` #### 6. **永久环境变量配置** 将环境变量添加到 `~/.bashrc` 文件: ```bash echo 'export PATH=$PATH:/home/kiki/aarch64-linux-android-4.9-toolchain-master/bin' >> ~/.bashrc echo 'export CROSS_COMPILE=aarch64-linux-android-' >> ~/.bashrc echo 'export ARCH=arm64' >> ~/.bashrc source ~/.bashrc ``` ### 常见问题排查 1. **路径格式错误** `CROSS_COMPILE` 值应以路径+前缀格式设置: ```bash # 正确格式 CROSS_COMPILE=/path/to/toolchain/bin/aarch64-linux-android- # 错误格式(缺少路径) CROSS_COMPILE=aarch64-linux-android- ``` 2. **32位兼容库缺失** 在64位系统上运行32位工具链需要安装兼容库: ```bash sudo apt-get install libc6-i386 lib32stdc++6 # Ubuntu/Debian sudo yum install glibc.i686 libstdc++.i686 # CentOS/RHEL ``` 3. **工具链版本不匹配** 确保工具链版本与目标内核兼容: - Android NDK r20+ 适用于内核 4.14+ - GCC 4.9 适用于旧内核 > **重要提示**:Android 内核编译要求严格的环境配置,建议使用 Google 官方推荐的构建环境 AOSP Build Environment[^4]。 ### 示例:完整的编译工作流 ```bash # 设置环境 export ARCH=arm64 export CROSS_COMPILE=/path/to/ndk/toolchains/aarch64-linux-android-4.9/bin/aarch64-linux-android- export PATH=$PATH:/path/to/ndk/toolchains/aarch64-linux-android-4.9/bin # 进入内核目录 cd /home/kiki/Desktop/5.1-common/out # 编译模块 make M=/home/kiki/Desktop/rwProcMem_module modules ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值