存于Google Drive的AppleScript损坏?深层技术问询
注:我并非询问解决方法、修复方案或为何不建议在Google Drive中保存AppleScript——这些我已知晓且已有解决方案。我仅希望从更深层面理解在Google Drive中保存AppleScript时会发生什么,以满足自身求知欲。
观察到的现象
- 在Google Drive的Scripts文件夹保存AppleScript多年,偶尔(每年约3次)会出现脚本突然无法运行的情况,此前直接替换副本未深究原因。
- 今日
complete_reminder.scpt脚本失效且无备用副本,排查发现:从Google Drive文件历史恢复副本并移出云端后,存在多个版本;推测每次通过Node-RED调用osascript命令运行脚本时,都会编译并保存脚本,进而生成这些版本。
代码差异对比
将受损版本的.scpt转为文本后,与恢复版本的diff如下:
diff complete_reminder_restored.osa complete_reminder_googles_mangled_version.txt 30c30 < set remWasRunning to (application "Reminders" is running) --- > set remWasRunning to (application "osascript" is running) 37c37 < tell application "Reminders" to quit --- > tell application "osascript" to quit 84c84 < tell application "Reminders" --- > tell application "osascript" 86c86 < set completed of every reminder whose completed is false and name is myTitle to true --- > set «class comb» of every «class remi» whose «class comb» is false and name is myTitle to true 88c88 < set completed of every reminder in list myList whose completed is false and name is myTitle to true --- > set «class comb» of every «class remi» in list myList whose «class comb» is false and name is myTitle to true 107c107 < tell application "Reminders" --- > tell application "osascript" 109c109 < set rems to (every reminder whose id is remid) --- > set rems to (every «class remi» whose id is remid) 112c112 < set completed of rem to true --- > set «class comb» of rem to true 124c124 < tell application "Reminders" --- > tell application "osascript" 127c127 < set rems to (every reminder whose id is remid) --- > set rems to (every «class remi» whose id is remid) 130c130 < set completed of rem to true --- > set «class comb» of rem to true
失效表现
脚本失效后,每次运行都会弹出询问osascript应用位置的窗口,无人响应则超时,Node-RED流程返回错误:Can’t get application "osascript".
提出的技术问题
- 是否是
osascript编译过程篡改了我的原始代码? - 导致编译出现该问题的诱因是什么?
- 为何会将"Reminders"替换为"osascript"?
- 为何该问题仅偶发出现?
技术解析
是否是
osascript编译过程篡改了代码?
不是osascript主动篡改代码。.scpt是编译后的二进制格式,存储的是应用脚本字典的引用而非明文代码。问题源于Google Drive的同步机制破坏了二进制文件中的字典引用映射,导致反编译时出现错误替换。编译出现问题的诱因是什么?
核心是Google Drive实时同步与AppleScript编译文件的写入冲突。当osascript运行.scpt时,可能临时写入或更新文件的元数据/编译信息;若此时Google Drive触发同步,会导致文件内容被部分覆盖或损坏。损坏的二进制文件反编译回文本时,就会出现术语映射错误。为何"Reminders"会被替换为"osascript"?
AppleScript编译文件中,应用术语(如Reminders)通过应用的签名或字典ID存储,而非明文。文件损坏后,反编译工具无法正确解析原始字典ID,会错误映射到当前执行编译/反编译的默认应用——即osascript,因此将Reminders替换为osascript。而completed这类属性因无法找到对应术语,被替换为底层类标识符(如«class comb»、«class remi»)。为何问题仅偶发出现?
冲突需要满足特定条件:
- Google Drive恰好在
osascript写入/更新.scpt的瞬间触发同步 - 系统资源紧张时,文件写入或同步的IO操作延迟,导致内容写入不完整
- Reminders应用的字典缓存出现临时异常,导致编译时术语映射暂时出错
这些条件并非每次运行都会满足,因此问题仅偶发出现,频率与Google Drive同步周期、系统负载等因素相关。
内容的提问来源于Stack Exchange,提问作者hepcat72

