关于sh: not found问题

文章详细记录了解决在QT210开发板上编译并运行helloworld时遇到的sh:notfound问题的过程。通过对比Android环境与GNU toolchain的编译方法,最终成功通过直接调用libc.so等库文件解决了动态库查找问题。

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

    今天原本准备在QT210开发板上跑个hello world。没想到用arm-none-linux-gnueabi-gcc hello.c编译运行后,出现sh: not found,初看起来应该和动态库有关,于是开始了一段长达8小时的艰辛之旅,期间获益不少,记录如下。

    首先,这款开发板预装的是android的环境,安卓环境的libc和gnu的libc有很多不同,编译过程区别也很大,我简单看了android平台下的makefile,一般代码的编译过程:

arm-eabi-4.4.3/bin/arm-eabi-g++   -c  -fno-exceptions -Wno-multichar -msoft-float -fpic -ffunction-sections -funwind-tables -fstack-protector -Wa,--noexecstack -Werror=format-security -fno-short-enums -march=armv7-a -mfloat-abi=softfp -mfpu=neon  -Wno-psabi -mthumb-interwork -DANDROID -fmessage-length=0 -W -Wall -Wno-unused -Winit-self -Wpointer-arith -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -DNDEBUG -g -Wstrict-aliasing=2 -finline-functions -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -DNDEBUG -UDEBUG -fvisibility-inlines-hidden -DANDROID -fmessage-length=0 -W -Wall -Wno-unused -Winit-self -Wpointer-arith -Wsign-promo -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -DNDEBUG -UDEBUG -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64  -fno-rtti      -MD-o hello.o hello.c

链接:

arm-eabi-4.4.3/bin/arm-eabi-g++ -nostdlib -Bdynamic -Wl,-T,build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -ohello-Lout/target/product/generic/obj/lib -Wl,-rpath-link=out/target/product/generic/obj/lib  -Wl,-z,noexecstack -Wl,--fix-cortex-a8   -Wl,--no-undefined   hello.o   

    简单分析一下:在链接时,指定了链接器/system/bin/linker ,还指定链接过程的搜索路径out/target/product/generic/obj/lib,用-Wl,-T排除了默认的链接方法,直接使用build/core/armelf.x 链接脚本,可见android的编译方法和普通的gnu toolchain在链接时有些不同。

    如果按以上方法编译helloworld,不免感觉杀鸡用牛刀。于是决定直接舍弃android平台,重启炉灶:

     1. 拷贝gnu toolchain的libc.so, ld-linux.so, libdl.so, libpthread.so到开发板/data/mylib目录下,建好符号链接文件。

     2. 重新编译hello.c: 

          arm-none-linux-gnueabi-gcc -Wl,-rpath=/data/mylib -static-libgcc -Wl,-dynamic-linker=/data/mylib/ld-linux.so.3 -o hello hello.c

                      -Wl,-rpath=/data/mylib 指定运行时搜索动态库的路径;

                     -Wl,-dynamic-linker=/data/mylib/ld-linux.so.3 指定运行时的链接器。

                      以上两项可以用readelf -a hello 查看program interpreter,Library rpath:两个字段。

      3. 运行OK.

      

       最后出现not found问题的原因总结如下: 

       1.  找不到动态库,一般是libc库;

       2.  c库不兼容,android的c库和用gnu toolchain里的c库不相容。

       3.  连接器没指定路径。程序在板子上跑需要指定连接器路径。

       4.  最后,有些朋友出现not found问题,还可能是eabi的版本不同造成,toolchain的版本和开发板上内核的版本不兼容。






### 解决 `sh: 1: : not found` 错误的方法 当遇到 `sh: 1: : not found` 类似的错误时,通常意味着存在一些基础配置或语法上的问题。以下是几种可能的原因及其解决方案: #### 使用正确的解释器 如果脚本中包含了特定于 Bash 的特性,比如条件测试 `[[]]`,那么应该确保使用 `bash` 来执行该脚本而不是默认的 `sh`。可以通过指定解释器来启动脚本,例如: ```bash #!/bin/bash ``` 这行应当位于脚本的第一行以指明应由哪个程序去解析此文件[^1]。 #### 文件权限设置 有时即使路径和命令本身都没有问题,但如果缺少可执行权限也会引发类似的错误提示。可以利用如下命令给定适当权限: ```bash chmod +x scriptname.sh ``` 这样就可以正常运行带有执行权限的 Shell 脚本了[^2]。 #### 文本格式转换 考虑到不同操作系统之间的差异,特别是 Windows 和 Unix/Linux 平台间的换行符区别,可能导致某些情况下读取不到预期的内容从而抛出异常。建议先确认源码是否已经过 dos2unix 工具处理,将其转化为适合 Linux 下使用的纯文本形式[^3]: ```bash dos2unix your_script_file.sh ``` #### 正确书写条件语句 对于包含逻辑判断的部分,注意保持良好的编程习惯——即在关键字之间保留必要的空白字符。具体来说就是保证 `if` 后面跟有一个空格;方括号内部的操作数两侧也要留白;比较运算符前后同样如此[^4]。 通过以上措施调整之后再尝试重新加载并执行有问题Shell脚本,一般能够有效消除此类报错现象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值