运行C可执行文件提示文件不存在错误但文件存在,求问题原因
这种情况我之前排查过好几次,先给你明确一点:不是可执行文件sf找不到(你能运行./sf就说明它存在且能被执行),错误提示是你的程序sf在运行过程中,尝试打开某个文件时失败了。下面是几个最常见的原因和对应的排查/解决方法:
可能的原因与解决方案
程序里用了相对路径,但目标文件不在当前工作目录
比如你的代码里写了fopen("config.dat", "r"),但这个config.dat文件根本不在你运行./sf的~/socket目录下,而是在你编译程序时的其他路径里。- 排查:直接查看
serverFile.c里的文件操作代码,找到要打开的文件名和路径;或者用strace ./sf命令跟踪系统调用,你会看到程序尝试打开的具体路径,一眼就能发现问题。 - 解决:要么把目标文件复制到
~/socket目录下,要么在代码里改成绝对路径(比如/home/root/socket/config.dat),或者运行程序前切换到目标文件所在的目录。
- 排查:直接查看
代码里的文件名拼写错误(Linux区分大小写)
比如代码里写的是fopen("ServerData.txt", "r"),但实际文件名是serverdata.txt,Linux是严格区分大小写的,这就会导致找不到文件。- 解决:仔细比对代码里的文件名和实际文件的名称,包括大小写、后缀名、有没有多余的空格。
动态链接库缺失(特殊场景下的误报)
有些老版本Linux系统(比如你用的3.10内核的Poky Edison),当程序依赖的动态链接库找不到时,可能不会直接提示库缺失,而是抛出类似“打开文件失败”的错误。- 排查:用
ldd ./sf命令查看程序依赖的动态库,检查有没有标记为not found的项。 - 解决:安装对应的库,或者把缺失的库文件放到
/lib、/usr/lib目录下,也可以临时设置export LD_LIBRARY_PATH=/path/to/your/libs来指定库的路径。
- 排查:用
文件权限或特殊挂载限制
虽然你用的是root用户,权限应该足够,但如果目标文件在外部存储设备(比如SD卡)上,而该设备是用noexec或其他限制权限挂载的,也可能导致程序无法读取文件。- 排查:用
ls -l查看目标文件的权限,确认root有读权限;用mount命令查看存储设备的挂载参数。 - 解决:调整挂载参数(比如去掉
noexec),或者修改文件权限为chmod 644 target_file。
- 排查:用
快速定位问题的技巧
最直接的方法是用strace ./sf命令,它会输出程序执行过程中所有的系统调用,其中肯定会有一行open(...) = -1 ENOENT (No such file or directory),后面跟着的就是程序尝试打开的错误路径,根据这个路径就能立刻找到问题所在。
内容的提问来源于stack exchange,提问作者Lightsout

