ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Py6S报错“6S executable not found”?从编译到配置的完整解决指南

2026/10/2 1:26:23 拓冰建站 浏览量
Py6S报错“6S executable not found”?从编译到配置的完整解决指南 做遥感反演和大气校正的人十有八九会在Python里碰上Py6S这个库。它是6S大气辐射传输模型的一个Python封装装上之后调参数、跑模拟、读结果比直接跟Fortran打交道舒服太多。但也正因为它是“封装”很多人第一次运行就会卡在同一个错误上6S executable not found。这个错误严格来说不是pip install阶段弹出来的而是你第一次真正调用SixS()构造器或者执行run()的时候程序直接甩给你的。字面意思是“找不到6S可执行文件”但实际坑比这句话多得多——你可能压根没编译过6S也可能编译了但路径没配对还可能编译器本身就没装对导致连可执行文件都没生成。我见过不少人卡在这里几天最后发现是“6S没有被编译”这个最简单的原因。这篇文章我不绕弯子直接按我自己的排查思路来写先把Py6S和6S的协作机制讲清楚再一步步带你完成源码获取、编译器准备、可执行文件编译、路径配置和最终验证。Linux、macOS、Windows三种常见场景我都会覆盖到尤其是Windows我会直接给出建议。1. 一个“找不到”背后的三层原因先搞懂Py6S和6S到底怎么协作1.1 Py6S只是“翻译官”不是“执行者”6S模型本身是用Fortran写的它接收的输入是格式非常严格的文本文件输出也是格式化的文本。Py6S这个Python库做的事情是帮你把这些输入文本按6S要求的格式拼好提交给6S程序运行再把6S的输出解析成Python对象。用一句话概括Py6S是翻译官真正干活的是那个Fortran程序。因此Py6S装好了并不代表6S就能跑。它还缺一个“被调用”的对象——也就是编译好的6S可执行文件。在Linux和macOS上这个文件通常叫sixs在Windows上叫sixs.exe它是从6S的Fortran源代码编译出来的。我看到太多初学者以为pip install py6s之后就算万事大吉结果第一次创建SixS实例时就被报错打懵。实际上pip只是把翻译官请进了门真正干活的“6S程序”必须自己准备。1.2 报错是在哪里被抛出来的用过的Py6S版本里源码中有这么一段逻辑当SixS对象初始化或者调用run()时它会去查找6S可执行文件查找顺序大致是环境变量SIXS_EXECUTABLE、Py6S内部维护的目录变量、当前工作目录。这些路径都没找到有效文件它就抛出一个RuntimeError消息内容就是6S executable not found。这个设计本身没问题问题在于它不会明确告诉你“你没编译”还是“路径没配对”。所以遇到这个错第一件事不是去瞎试路径而是先确认机器上到底有没有一个能用的sixs程序如果有它是在哪个路径如果没有问题根源就是编译这一步还没完成。1.3 为什么很多教程都默认你已经有了6S可执行文件我查过不少博客和文档发现一个很普遍的现象大部分教程一上来就直接写from Py6S import SixS s SixS() s.run()然后默认一切正常。但很少有教程会说明6S可执行文件是需要单独下载源码、手动编译的。这些教程默认读者是“已经编译过6S”的群体新手一踩一个准。所以我这篇文章干脆从零开始讲把编译和配置过程完整拆开。2. 动手之前先备齐三样东西源码包、Fortran编译器、正确的Python环境2.1 6S源码哪里下版本怎么选6S源码的官方发布渠道是6S项目主页下载最新版本源码压缩包即可。如果官方站点访问速度不理想GitHub上也有镜像仓库搜索“6S”能找到。下载后解压你会看到一堆.f、.f90、.dat文件以及README或Makefile。这里有个关键点源码包里的数据文件那一堆.dat文件和源代码文件一样重要。编译出来的可执行文件在运行时会读取同目录下的这些数据文件。也就是说不能只把编译出来的sixs二进制拷到别的地方数据文件必须和它待在一起。这一步很多人忽略后面会引发各种稀奇古怪的运行时错误。2.2 Fortran编译器选型选gfortran准没错6S是Fortran 77时代的老代码目前最通用、最不容易出问题的编译器是gfortran。它开源、免费在Linux和macOS上安装都很方便兼容性也比一些商业编译器更省心。Linux Debian/Ubuntu系列sudo apt install gfortranLinux CentOS/RHEL系列sudo yum install gcc-gfortranmacOSbrew install gcc注意macOS上执行brew install gcc会带上gfortran不需要单独装gfortran包。如果你还没装Homebrew先去把Homebrew装了这一步不展开。Windows我的建议是别在原生环境硬折腾优先用WSL2。在WSL2的Ubuntu里装gfortran然后走Linux流程。如果非要原生Windows那就装MinGW-w64提供的gfortran但后续路径、数据文件的问题会比Linux多不少我后面会专门讲。6S这种老代码用gfortran而不是ifort还有一个现实原因ifort的许可证获取和配置更繁琐用它编译老Fortran代码也未必比gfortran顺手。对一个科研工具来说不划算。2.3 Python版本和Py6S版本的搭配建议Py6S对Python 3的支持已经很成熟直接用pip安装即可pip install py6s但如果你在conda环境里工作我强烈建议建一个干净环境再装避免numpy、scipy等依赖和已有环境冲突conda create -n py6s python3.9 conda activate py6s pip install py6sPython版本不要太新。3.12甚至之后的版本Py6S依赖的numpy/scipy在那些环境里偶尔会有编译安装问题。我实际用的是Python 3.9跑得很稳。如果你在安装Py6S阶段就已经遇到一堆编译报错多半是Python版本太新或缺少开发头文件这种问题建议直接换成3.9环境重装别浪费时间逐个解决。3. 真正的重头戏把6S源码编译成可执行文件3.1 Linux编译看起来只有一条make命令实际上有几个隐藏点在Linux下进入解压后的6S源码目录cd 6S_V1.1 ls如果目录里有Makefile理论上直接make就能生成sixs可执行文件。但有一个常见情况机器上有多套编译工具链或者环境变量FC没设对导致make报一些Fortran匹配错误。这时候可以直接指定编译器再编make clean make FCgfortran如果连Makefile都没有或者make总是失败那就直接手动编译所有源文件gfortran -O2 -o sixs *.f有些版本里源码是.f90那就把两种都编译进去gfortran -O2 -o sixs *.f *.f90编译完成后先做一个简单的自测./sixs如果程序马上提示你输入参数或者打印一段用法说明说明可执行文件没问题。6S的设计是从标准输入读参数所以直接回车几下它大概率会报“输入行错误”之类的话这反而是好事说明程序真的在运行。然后检查一下数据文件是否齐全ls *.dat | wc -l如果数量是0说明你下载的源码包不完整需要重新下载完整压缩包。3.2 macOS编译常见报错和解决思路macOS比Linux多两个门槛。第一个门槛执行make会提示找不到命令。这时先安装Xcode Command Line Toolsxcode-select --install第二个门槛macOS自带的clang编译器不认Fortran所以必须确保gfortran已经可用。用Homebrew安装brew install gcc装好后进入源码目录编译cd 6S_V1.1 make FCgfortran如果你遇到类似ld: library not found for -lgfortran的链接错误通常是gfortran的库路径没被编译器找到。可以用which gfortran查一下安装位置然后设置LIBRARY_PATH但最省事的办法其实是brew reinstall gcc然后重新编译基本能过。Apple SiliconM1/M2/M3系列上我也实测过只要gfortran是arm64版本编译没问题。3.3 Windows编译别在原生环境硬磕WSL2是最省心的路在Windows原生环境编译6S理论上可行但会碰到很多和路径、数据文件读取相关的坑。如果你要长期做遥感数据处理我强烈建议用WSL2在里面创建一个Ubuntu环境然后完全按Linux流程来。优点显而易见编译器环境干净、Py6S的运行环境和编译环境一致、后续再装GDAL等依赖也不会拖泥带水。如果你就是想在Windows原生环境里编译需要装MinGW-w64把gfortran加入PATH然后在CMD里进入源码目录cd /d C:\6S_V1.1 gfortran -O2 -o sixs.exe *.f编译成功后会生成sixs.exe同样要保证所有.dat文件就在同一个目录。但后续Py6S在Windows下调用它可能还会遇到路径分隔符和权限问题。所以我的态度很明确能用WSL2就用WSL2别跟这个老Fortran程序较劲。Windows上不是不能跑而是你花在折腾环境上的时间足够把数据跑完好几轮了。3.4 编译完成后的三个自查点可执行文件确实生成了吗执行ls -l sixs文件大小一般是几十KB到几百KB。数据文件是否和可执行文件在同一个目录所有.dat文件都要在。命令行执行./sixs有没有“程序能跑”的反馈哪怕报参数错误也算活着的程序。4. 让Py6S找到6S三种配置方式任选一种即可可执行文件已经就绪接下来要让Py6S运行时能定位到它。我按推荐程度列出三种方式。4.1 方式一设置环境变量SIXS_EXECUTABLE最推荐Py6S默认会读取环境变量SIXS_EXECUTABLE来定位可执行文件的完整路径。这是最不容易受Py6S版本升级影响的方案也是我最推荐的方式。Linux/macOS临时生效export SIXS_EXECUTABLE/home/user/6S_V1.1/sixsWindows临时生效set SIXS_EXECUTABLEC:\6S_V1.1\sixs.exe想要永久生效Linux/macOS下把这行写到~/.bashrc或~/.zshrc里Windows下在系统环境变量里新建。配置完先检查变量是否写对echo $SIXS_EXECUTABLE注意一个细节如果路径里有空格建议把可执行文件先复制到一个无空格的目录比如/usr/local/bin/sixs。老程序对带空格的路径处理非常不友好这个坑在后面迟早会遇到。4.2 方式二直接修改Py6S源码里的默认路径如果你不想每次开终端都设置环境变量可以直接改Py6S包内部的配置。先找到Py6S的安装目录python -c import Py6S, os; print(os.path.dirname(Py6S.__file__))然后打开里面的sixs.py或__init__.py不同版本位置略有差异搜索sixs_directory和sixs_executable这两个变量。它们就是控制可执行文件位置的关键sixs_directory /home/user/6S_V1.1/ sixs_executable sixs改成你自己的路径保存后重新测试。这个方案的好处是一次配置永久生效缺点是一旦升级Py6S改动可能会被覆盖需要重新修改。所以我在自己机器上更倾向于环境变量方案。4.3 方式三在Python脚本里动态指定如果你只想临时跑个脚本不想动系统配置可以在导入Py6S之前把环境变量放进os.environimport os os.environ[SIXS_EXECUTABLE] /home/user/6S_V1.1/sixs from Py6S import SixS s SixS() s.run()这里有个非常重要的经验设置环境变量的语句一定放在from Py6S import SixS之前。我之前一个同事死活找不到可执行文件排查到最后发现他把os.environ那句写在了import之后。Py6S在导入阶段就已经读取过环境变量之后再写当然没用。4.4 配置完怎么验证别急着跑大模型配置完成后的最快验证方法from Py6S import SixS s SixS() print(created successfully)如果能打印出created successfully说明Py6S已经找到6S可执行文件。接下来跑一个最小的计算流程s.run() print(s.outputs.pixel_radiance)这一步会真正触发6S计算。如果前面配置有问题异常会在run()时抛出而不是构造时。还有一个更直接的排查方式在Python里打印Py6S内部的查找路径然后确认文件是否存在from Py6S import sixs import os path sixs.sixs_directory sixs.sixs_executable print(path) print(os.path.exists(path))如果结果是False说明配置仍然没指向真实文件回到上面三种方式重新检查。5. 跑通之后才刚开始最小示例和真实使用中的注意点5.1 最小示例算一组大气参数配置完成后我常用下面这段代码来验证整个环境from Py6S import SixS from Py6S.Params import AtmosProfile, AeroProfile, Wavelength s SixS() # 使用热带大气剖面 s.atmos_profile AtmosProfile.PredefinedType(AtmosProfile.Tropical) # 使用大陆型气溶胶模型设置550nm处的AOD为0.3 s.aero_profile AeroProfile.PredefinedType(AeroProfile.Continental) s.aot550 0.3 # 设置波长、太阳天顶角、卫星天顶角 s.wavelength Wavelength(0.55) s.solar_z 30 s.satellite_z 10 # 运行6S s.run() # 查看结果 print(s.outputs.pixel_radiance) print(s.outputs.transmittance_atmospheric)能打印出数值就说明整条链路是通的。5.2 真实场景里容易忽略的事数据文件与运行目录前面反复强调数据文件这里再具体说一下。6S运行时不只是需要那个可执行文件它还需要读取很多地表和大气参数表这些表格就是源码包里的.dat数据文件。如果你把sixs单独复制到/usr/local/bin却把数据文件漏了Py6S运行时会报一些看起来和路径无关的错误比如找不到某个大气剖面、输出结果异常甚至直接崩溃。解决方式很土但很稳直接在源码目录里调用它。只要SIXS_EXECUTABLE指向源码目录中的sixs数据文件就在它旁边整个运行过程就不会有问题。这也是为什么我习惯把6S整个源码目录固定放在~/tools/6S_V1.1而不是只拷贝二进制。5.3 批量处理影像时的建议做批量遥感影像大气校正时很多人的第一反应是循环里反复创建、销毁SixS实例。这个做法虽然可行但每次创建都会做很多初始化工作浪费不少时间。我自己的习惯是如果只是针对不同波长或不同角度循环就先把SixS对象创建出来循环里只改对应参数然后调用run()如果必须用多进程加速再考虑创建多个进程副本运行。这个小技巧不复杂但在大量数据场景下能省下不少时间。6. 我在实际使用中踩过的坑和排查思路这一节专门记录高频但零散的问题每条都是我实际碰到过或者帮别人排查过的。6.1 明明编译出了sixsPy6S还是报not found先别急着重新编译按下面顺序检查在终端执行which sixs如果命令能显示路径说明可执行文件在PATH里但Py6S不一定走PATH它更信任环境变量或包内路径。确认SIXS_EXECUTABLE指向的是可执行文件本身而不是所在目录。这个细节特别容易搞错有人把路径写成目录Py6S去拼成“目录/sixs”自然找不到。6.2 run()报错变成nonzero return code如果你已经越过了not found却在run()时看到类似return codenonzero的报错绝大多数情况是6S程序本身运行失败了。常见原因有三个数据文件没配对也就是.dat文件缺失或不在当前目录。输入参数超出6S的合理范围比如太阳天顶角为负数、波段定义不合法。工作目录不可写6S需要生成临时文件当前目录没权限就会失败。处理办法手动在命令行里./sixs输入一份和Py6S类似的参数看6S到底抱怨什么。或者写一段代码捕获6S的标准输出把实际运行信息打出来问题基本就显形了。6.3 Windows路径空格和中文字符Windows下如果把6S放在C:\Users\张三\6S Model\这种路径下大概率会出幺蛾子包括not found和运行时崩溃。解决方案只有一个直接放到C:\6S\这种纯英文、无空格、层级浅的目录下。这能解决掉一大半Windows相关的问题。6.4 升级Py6S后突然坏了Py6S版本偶尔会调整内部调用方式升级后有可能改变配置变量名或默认行为。遇到这种情况先想想自己原来的配置方式是什么如果依赖环境变量SIXS_EXECUTABLE升级后通常最稳。如果之前改了包内源码升级后改动会被覆盖自然回到找不到可执行文件的“出厂状态”。处理方法是重新改一次包内配置或者索性切到环境变量方案一劳永逸。6.5 快速定位问题的最小化复现法当你被一连串报错绕晕时我建议做一个最小化复现。只设置环境变量写一个五行以内的脚本跑SixS().run()import os os.environ[SIXS_EXECUTABLE] /path/to/sixs from Py6S import SixS s SixS() s.run()如果这个能过说明环境是好的问题出在你的业务代码如果连这个都过不了说明就是6S可执行文件或配置的问题。二分法定位永远比瞎猜效率高。最后再分享一个我亲测有效的习惯刚换新电脑配Py6S时我会把整个6S源码目录连同数据文件一起归档到固定的~/tools/6S_V1.1然后在~/.bashrc里写死export SIXS_EXECUTABLE~/tools/6S_V1.1/sixs。这样每次换环境、换Python版本都不用重新记路径。真遇到问题就从最小复现开始查。这个错误的本质其实一点也不复杂——Py6S只是个翻译官你要确保那个真正干活的Fortran程序存在、能运行、并且被正确指过去。把这三个问题逐一确认过6S executable not found基本就能彻底告别了。