公司那台 Dell Precision 5860,i7-12700,64G内存,1T的NVMe固态。系统Win11专业版,上面套了一层 VMware Workstation 17,虚拟机里跑的 Ubuntu 22.04,装的是 Abaqus 2022。为什么要套虚拟机?因为正版license服务器绑在IT部门的域控上,物理机装驱动会跟公司的DLP软件打架,我懒得扯皮,直接虚拟机走桥接模式连license。
这套环境我用了大半年,跑静力学、跑模态都没毛病。上周接了个瞬态热-力耦合的活,网格划了87万单元,增量步设了四百多步,算完之后我去工作目录找odb文件——没有。
Job Manager里状态写的 Completed,绿勾,看着挺正常。但终端日志最后几行甩了我一脸:
Abaqus/Standard completed successfully.
The output database file job_thermal.odb could not be written to directory /mnt/hgfs/shared_sim/.
Error: Permission denied.
Permission denied。经典三件套。
更恶心的是,我切回Windows宿主机的共享文件夹一看,目录里躺着 .dat、.msg、.sta、.sim 一堆零碎文件,唯独 .odb 这个最要紧的结果数据库没写进去。求解器算完了,数据在内存里转了一圈,最后落盘的时候被操作系统一巴掌拍回来了。
我承认我第一反应是骂了句脏话。Abaqus的报错信息永远是这种"告诉你出错了但不告诉你为什么错"的风格,二十年了,达索是真不打算把error message写成人话。你去搜官方知识库,搜到的全是"please check your file permissions"这种正确的废话。生态不友好这件事,从license文件要用flexlm那套上世纪的守护进程开始,到报错日志永远差一句人话,贯穿始终。
第一轮怀疑:虚拟机共享文件夹的锅。
VMware的 /mnt/hgfs 这个挂载点,懂的人都懂,它不是真正的ext4文件系统,走的是HGFS协议,对文件锁和权限位的支持一直拉胯。我怀疑odb写入的时候需要独占锁或者创建临时文件,共享文件夹的驱动不支持,直接被拒了。
验证方法很简单,我把工作目录改到虚拟机本地的 /home/sim/abaqus_work/,重新提交一个小job测试。结果——还是报Permission denied。
好,共享文件夹排除。
第二轮怀疑:网络适配器跟license冲突。
因为我的虚拟机是桥接模式,网卡直接挂在物理网段上。我琢磨是不是license校验的时候占用了某个文件描述符,或者license daemon跟I/O线程抢锁。我甚至去改了 license 文件里的 SERVER 那行,把主机名换成了固定MAC地址绑定,重启lmgrd。
没用。小job照样写不进去。
第三轮怀疑:Linux文件权限。
我 ls -la 看了目录,755,属主是我自己。chmod 777 也试了。umask 从022改成000也试了。甚至用root跑了一遍。
还是不行。
到这儿我已经卡了差不多二十五分钟。我开始怀疑是不是SELinux或者AppArmor在背后拦截,虽然Ubuntu默认不开SELinux,但AppArmor是开着的。我 sudo aa-status 看了一眼,abaqus相关的进程没被profile限制。

第二十八分钟的时候我冷静下来,把报错信息又看了一遍。注意那句:
could not be written to directory /mnt/hgfs/shared_sim/
但我刚才明明把工作目录改到本地路径了啊?为什么日志里还写着 /mnt/hgfs/shared_sim/?
我打开 abaqus_v6.env 一看,里面有一行:
workDirectory = '/mnt/hgfs/shared_sim/'
这是半年前我图省事,想直接在Windows资源管理器里看结果文件,把全局默认工作目录写死在了配置文件里。我在CAE里用 File > Set Work Directory 改的只是当前会话的临时路径,但Job提交的时候,abaqus_v6.env里的workDirectory优先级更高,直接把输出目录拽回去了。
而 /mnt/hgfs/shared_sim/ 这个路径,因为VMware Tools那天早上自动更新重启了hgfs服务,挂载点实际上已经断了,变成了空目录且不可写。所以Permission denied。
修复方法:
/home/sim/abaqus_work/。sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other。半小时,就这么没了。
折腾完之后我把odb这套东西重新梳理了一遍,省得下次再犯蠢。
odb根本不需要你手动保存。 这玩意儿是求解器算完之后自动生成的二进制数据库,文件名就是 job_name.odb,躺在你设的工作目录里。它不像.cae模型文件需要你Ctrl+S。Job跑完,文件就在;Job没跑完或者中途报错终止,文件要么是残缺的要么压根不存在。
想改odb生成位置,改工作目录。 CAE里 File > Set Work Directory 是临时改当前会话的;想永久改,去动 abaqus_v6.env 里的 workDirectory 参数。别两个地方设成不同路径,会打架。
odb不能"另存为"。 我见过有人试图把odb改后缀变成STEP或者IGES,然后拿SolidWorks去开。这不可能。odb里面存的是网格节点上的场变量数据——应力、应变、位移——它不是参数化几何模型,没有B-rep拓扑信息,任何CAD软件都读不了。强行改后缀只会得到一个打不开的文件。
想从odb里拿数据出来,走这几条路:
from odbAccess import openOdb 读取最后一帧的节点坐标和位移场,自己拼三角面片写STL。十几行代码的事,但CAE界面确实不给你点按钮的机会。odb以只读模式打开的坑: 如果你从别人那儿拷了个odb文件,Windows上大概率带只读属性。你在Visualization里画了条XY曲线想存回odb里,右键Copy to ODB会报错。去文件属性里把Read-only取消勾选,或者干脆复制一份出来再操作。

方案一:用Python脚本提交Job的时候直接锁死输出路径。
mdb.Job(name='thermal_run', model='Model-1',
workDirectory='/home/sim/results/')
mdb.jobs['thermal_run'].submit()
脚本里写死的workDirectory优先级最高,不会被env文件覆盖。批量跑参数扫描的时候我基本都这么干,省得每次都去确认目录对不对。
方案二:写个cron定时任务备份odb。
odb文件一旦生成就是不可变的,不存在"没保存"的风险,但有被误删的风险。我在虚拟机里加了条crontab:
0 2 * * * find /home/sim/abaqus_work -name "*.odb" -mtime -1 -exec cp {} /backup/sim_results/ \;
每天凌晨两点把过去24小时内新生成的odb文件复制到备份盘。跑一次大瞬态动辄十几个小时,万一硬盘抽风或者手滑rm了,不至于哭。
第一,abaqus_v6.env里不要写死workDirectory。 或者写了就在旁边加注释提醒自己。这行配置的优先级高于CAE界面设置,特别容易忘。我现在干脆把这行注释掉了,每次提交Job在脚本里显式指定路径。
第二,虚拟机里不要依赖共享文件夹做计算输出目录。 HGFS的I/O性能和权限支持都不行,写个几GB的odb文件容易出幺蛾子。老老实实用虚拟机本地磁盘路径,跑完了再手动拷出去或者scp出去。
第三,提交Job之后先别关掉终端,看一眼最后三行日志。 Abaqus的日志结尾会明确告诉你odb写到了哪个路径。花五秒钟确认一下,总比算完四个小时发现文件不在该在的地方强。
第四,输出频率别设太密。 瞬态分析四百个增量步,如果每步都写全场输出,odb能膨胀到几十GB。Step模块里Field Output Request的Frequency改成每隔N个增量步输出一次,或者按固定时间间隔。文件小了,写入也快了,磁盘I/O压力下来了,Permission denied这种问题出现的概率也跟着降。
就这些。下次再遇到Permission denied,别上来就怀疑权限位,先确认路径到底是不是你以为的那个路径。我半小时的教训,够你省半小时了。