本文长期更新,更新日志见文末。
本系列不是“入门”,至少不是传统意义上的入门。吾生而有涯,何来时间入门那么多东西?何况,在一百个领域成为半吊子,似乎也不是什么值得高兴的事。本系列文章旨在解决问题,介绍一些通用技能,它们往往因为貌似诘屈聱牙而被忽略,但实际上大有可为:正则表达式、通配符、命令行、Javascript、列编辑……我无法向你作出产品经理式的承诺,保证你看完文章旋能突飞猛进、一步登顶,但你很可能发现,许多 Power User 已经将这些技能锻入骨髓,随口念上一句“现在使用某某技能”,文章就峰回路转,教程就妙笔生花。这是数字世界居民的通用技能,这就是赛博空间的通行语言,因此,每个普通人都可以、也应当多多少少掌握它们。
或许 GPT 为首的一批大型语言模型(LLM)会让这系列文章黯淡不少,但如果没有人来写,人工智能又去哪里抄呢?苟你坐享其成,若我坐收渔利,无疑只会导致公地悲剧。
macOS 拥有良好的自动化生态,从原生的 AppleScript、Unix 脚本、Automator、Shortcuts 到第三方的一众自动化工具——Keyboard Maestro、LaunchBar、Alfred、Hazel、Dropzone……俨然一处森森庭院。
不过,正如在庭院中嬉闹的孩童容易摔跤或者被虫子叮咬,自动化玩家们也是“常在河边走,哪有不湿鞋”,时而碰壁,时而铩羽,时而弄巧成拙。其实,若能获得一本相对可靠的指引,这些弯路也会成为探索的一部分,凝华为宝贵经历。诚然,落笔的图文只能抓住雅典娜的衣角,最好的领路人仍然是社区前辈与旅行者自己;但只要这本薄薄的册子中有一行文字能够帮到读者,作者就应当满足。
在您开始之前……
包括“重启解决一切在内”,有大量近乎于民间偏方的解决方案,它们不一定有效但基本无害,因而总能够产生奇效(不生效的案例不会被提及)。在尝试排查具体问题之前,这些方子值得您一试。关于这些偏方,没有人总结得比 hoakley 更好了,他让我的零散积累羞于示人,我只能把他总结的清单摘录如下,并建议您阅读原文:
- 重启(Restart)
- 进入安全模式(Safe mode)
- 重置 PRAM/NVRAM(Zap PRAM/NVRAM)1
- 重置 SMC(Reset SMC)2
- 硬件诊断(Hardware diagnostics)
- 启动卷中的急救选项(First Aid)
- 新建用户(New User)
Shortcuts 专门问题
作为原生自动化工具,Shortcuts 从 Workflow 演变而来,如今已覆盖了 iOS、iPadOS、macOS 和 watch OS,且很可能会接替上一代图形化自动化工具 Automator。但凡举被收购的软件,多少都会遭到“后妈”式的对待,更新和修复速度不可和小团队时期同日而语,至今除了一大批遗留多年的 bug,也常常与新系统——尤其是 macOS——发生龃龉。
无法共享大量数据
Shortcuts 常被用于批处理,例如压缩一大批图片,或者添加一系列日程,但你可能会马上吃瘪:This action is trying to share xx tems, which is not allowed.
这种情况,多为 Shortcuts 默认设置中的保护机制所致,可尝试在 Shortcuts 系统设置中勾选“Allow Sharing Large Amounts of Data”。
无法将XXX转换为YYY
我常在文章和留言中批评,被收购后的 Workflow 径直从 Python 退步到 VB——您不知道VB?不用被这玩意儿荼毒,真是太好了!——意思是,原本您根本不需要担心数据类型,Workflow 会自动处理,而在 Shortcuts 中,通常要强制指定类型,以免 Shortcuts 无法识别。
例言之,如果你在文本框里填了一段链接,然后尝试打开它,在 Workflow 时代不会有任何问题;而换作 Shortcuts,则要先把文本类型转换为链接。加之每次升级系统或分享 Shortcuts 动作,都可能重置变量类型,导致手动设置也会被清零,雪上加霜。
总之,如果你遇到这类问题,请点击变量并手动设置类型——在最糟糕的情况下,或许需要把文本转换为富文本、再转换为 HTML、再转换为 Markdown、再生成富文本、再提取纯文本,最后才能正常读取!
无法从列表所选项(Choosen Item)中获取数据
如上一所言,这是 Shortcuts 的一个经典 feature,即每次系统升级都看天才设计师的心情,把原本的变量类型改掉。而 Choosen Item 尤其特殊,不知从何时开始,它的类型竟然变成了“类文件”——有标题、修改时间、创建时间等等一系列属于文件的属性。尽管不是真正意义上的文件,可就凭 Shortcuts 比 VB 还脆弱的容错能力,这一点点的变量差异就足以让后续动作全部完蛋,例如直接根据 Choosen Item,您将无法从词典中获取任何数据;用 If 去判断 Choosen Item,也仅有“有”和“无”两个选项,再无任何其他条件可选……
解决方法也让人大跌眼镜,竟然要专门获取 Choosen Item 的 Name,才能真正获得其中的文本,而正常获取 Text 将虽然也可以获得数据,后续的动作却不认可它,无法往后传递。
无法在网页上运行 Javascript(macOS)
macOS 13 之后,Safari 终于可以通过分享菜单运行 Shortcuts 动作,这让一大批 iOS 上的网页自动化动作登堂入室,在桌面系统上抢滩登陆。不过,相当一批与网页交互的 Shortcuts 动作用到了 Javascript,而在默认情况下,您很容易看到以下提示:“Unable to Run JavaScript on Web Page”(无法在网页上运行 Javascript)。
这是因为,Shortcuts 内嵌的 Javascript 需要通过 Apple Event 方式运行,而出于安全考虑,该选项默认关闭。您可以先开启开发者菜单(Develop),再勾选“Allow JavaScript from Apple Events”。随后 Safari 会要求确认,并需要输入密码或生物识别。
Shortcuts 动作无法运行
运行 Shortcuts 的途径很多,包括主屏幕图标、Spotlight、分享菜单以及自动运行,但由于设备运行内存不足或者数据传输失败3,从前述渠道运行的 Shortcuts 有一定机率会失败(个人经验:在开启大量软件或电量不足时,经常会运行失败)。
显然,只要不是 Shortcuts 本身设计有误,通常重启手机或平板电脑就可以正常运行 Shortcuts 动作。还有一种更加无痛的方案:直接在 Shortcuts 应用内部运行,可以避开多数的内存和数据传输问题。
Shell 脚本相关
运行第三方命令行工具,无法找到命令(command not found)
许多自动化脚本用到了第三方命令行工具,我以前写过一个压缩图片的工具,就使用了一扎外来工具,部分读者曾发现无法运行——但是在 Terminal 中,命令似乎又是正常的。
原因在于,用过脚本运行第三方命令时,需要在脚本开头加点料:#PATH=$PATH:/usr/local/bin/
。
缺少 Xcode 命令行工具
问题症状表现为 LaunchBar 等依靠脚本的自动化工具无法运行、部分网络调试工具无法开启或 Git 相关命令找不到,常见于更新系统之后,尤其是大版本更新。
如明确收到 xcrun error 提示,则需要重新下载 Xcode 命令行工具——注意,不是完整的 Xcode,仅仅是命令行工具。安装命令如下:
xcode-select --install
另见:《升级 macOS 系统后,运行 git pull 报错的解决方法》(付费)。
zsh 不支持输入中文
方案一:在脚本开头添加以下代码。
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
方案二:修改 Terminal 本身的文本编码。
AppleScript 相关问题
AppleScript 是 macOS 的原生脚本语言,常用于控制软件(需软件本身支持,或至少采用原生框架开发),例如命令特定编辑器打开文档、指示 Safari 打开链接或让 Shortcuts 运行某个动作。
Apple Developer 文档是 AppleScript 的权威参考资料,但其更新并不及时,近年来的诸多语法调整(例如分隔符的变动)几乎未见诸任何文档,因而坊间更依赖论坛讨论和第三方指南(比如这个)。
本节将陆续收录常见的 AppleScript 自动化问题,更一般性的问题,请尝试在 Automator 论坛、MacScripter 或 MPU 等社区中自行检索。
无法控制软件
症状:下载的 AppleScript 脚本无法使用,也未见报错。或者在一个自动化工具中可用的脚本,移植到别的工具上就无法使用。再或者,某个动作在A软件中生效,但在B软件中就无效。
原因:在涉及 tell
语法——AppleScript 最重要的语法——时,AppleScript 需要您授权,以便控制目标软件。问题在于,每次在一个新的软件中运行 AppleScript 时,AppleScript 都会重新要求授权,以下是在输出中的提示,而一般的软件运行失败就不了了之,不会有提示或提示不明显,导致许多人以为脚本本身出错。还有一种可能是,AppleScript 曾向您申请授权,但是未获批准,久而久之使用者自己也忘了此事。
尝试:在系统安全设置中找到“Automation”一项,进而翻到出问题的软件,并授权它控制目标软件。尽管设置界面中并未出现“AppleScript”字样,但实际上就是指通过 AppleScript 在A软件中控制B软件。
提醒:请勿授权非官方来源的软件控制其他软件。
Python 脚本相关
不能运行 Python 脚本
症状:无法运行带有 Python 的脚本。常见于 LaunchBar 和 Dropzone 等以 Python 为主要脚本语言的工具。尤其在 LaunchBar 提示“The script is invalid”时,大概率是本节问题。
尝试:
- 检查您的脚本所用的 Python 版本:部分脚本仍然是用 Python2 写的,而 Python2 已经被 macOS 从系统中 删除,因此不能直接运行。对于不懂编程的人而言,如果脚本中没有注释具体版本号,那么判断 Python 版本最简单的办法就是查看
print
语句,如果是简单print
,就是 Python2;如果是带括号的print()
,则是 Python3。 - 检查电脑上是否已安装 Python:自 macOS 12.3 以降,系统就不再预装 Python,因此需要手动安装才能运行 Python。您可以使用任何喜欢的方式,尽管我推荐使用 HomeBrew。安装和修改脚本的完整流程如下:
- 在 Terminal(终端)中输入命令,安装 HomeBrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
; - 接着输入命令,安装 Python3:
brew install python@3.10
(此为截至 2022 年 11 月 16 日的最新版); - 继续输入命令,检查 Python3 位于何处:
which python3
; - 将上一步的结果粘贴到脚本开头:
#!/usr/local/bin/python3
,并将原有的#!
开头的那行删掉。4
- 在 Terminal(终端)中输入命令,安装 HomeBrew:
Python 不能输出中文
一个简单的编码问题。许多外国人编写的脚本当然不会考虑中文——以及其他东亚地区文字——直接下载,往往能够运行,但是字符显示异常。将以下文本粘贴到 Python 脚本开头即可:
#-*- coding: utf-8 -*-
#coding=utf-8
URL Scheme 相关
症状:URL Scheme 无法运行,或者运行不如预期,比如只运行了一半,后面设置的具体参数都没有被识别。
尝试:
- 按照操作步骤修改您自己的数据:有些 URL Scheme 下载后可以直接使用,而有些则不然,例如需要设置文件保存位置的,往往就需要您手动修改一下存储路径。建议先完整阅读文章,检查是否已经修改相关部分。
- 检查是否夹杂空格:许多输入法会自动添加空格,而 Shortcuts 也会在输入变量后画蛇添足,这都会导致 URL Scheme 无法被正确识别,空格之后的内容都被忽略了。
- 尽量不要使用中文:部分软件可以理解 URL Scheme 中的中文,但也有很多软件不行,例如 DEVONthink 在编辑模式下就不能直接打开夹杂中文的链接。如果您的 URL Scheme 中有中文,请尝试将它们进行 URL 编码,可以在网上找到很多现成工具,也可以下载我的这个 Shortcuts 调试工具,在里面找到 URL Encode 功能。
Keyboard Maestro 专门问题
Keyboard Maestro 是一款著名的 macOS 自动化工具,由独立开发者 Peter 创作。其功能包含处理文件、加工字符、和浏览器交互、GUI Scripting 以及运行脚本,涉及几乎所有你能想到的自动化问题。因其功能过多、设置甚繁,故出现疑难杂症也更为频繁。
Keyboard Maestro 无法与软件交互
Keyboard Maestro 通常需要通过 Apple events 与软件交互,例如模拟点击菜单栏选项。如果您第一次用 Keyboard Maestro 控制某个软件,或者曾经不慎拒绝过 Keyboard Maestro 的请求,可能看到如下通知:
请尝试在“System Settings - Privacy & Security - Automation”中找到 Keyboard Maestro,并勾选您需要控制的软件。
Keyboard Maestro 无法设置快捷键
正如其名字,Keyboard Maestro 最常见的启用方式是快捷键。但在升级系统或初次安装 Keyboard Maestro 时,可能发现 Keyboard Maestro 中设置的快捷键并不能正常工作,这一般是因为 Keyboard Maestro 及其配套引擎没有获得授权。
尝试前往“System Settings - Privacy & Security - Accessibility”,点击下方的加号“+”添加 Keyboard Maestro 及其引擎。Keyboard Maestro 引擎的位置比较隐蔽,位于 /Applications/Keyboard Maestro.app/Contents/MacOS/Keyboard Maestro Engine.app
,需要先找到 Keyboard Maestro 软件,在右键上下文菜单中点击“Show Package Contents”才能显示。
参考资料:
Keyboard Maestro 在 Safari/Chrome 中不工作
症状:包含 Javascript 的 Macro 无法在 Safari 或 Chrome 等浏览器中使用。
尝试:允许在浏览器中执行 Javascript,它们默认可能是关闭的。以 Safari 为例,您需要:
- 打开 Safari 浏览器,进入设置页面,在“Advanced”菜单中启用开发者菜单,即勾选“Show Develop menu in menu bar”(不同版本的 Safari,该选项位置也有差异,找不到的话可转道“General”标签页一试);
- 在开发者菜单中勾选“Allow JavaScript from Apple Events”;
- 选择同意“Allow”,可能需要输入密码或验证指纹。
Keyboard Maestro 在 macOS 13 的 Safari 中不工作
症状:如标题。尤其是 Keyboard Maestro 在其他软件中正常运行,或者在升级 macOS 13 前一直正常的的话,极有可能是本节所指向的问题。
尝试:如果你的 Keyboard Maestro 在升级到 macOS 13 Ventura 之后,不能使用 Safari 专用动作,可以尝试在 Macro Group 设置中重新选择“Safari”,即:把快捷方式图标的 Safari 换成正常的 Safari。
特别是在 Keyboard Maestro 中可以运行动作而在 Safari 中无法运行时,如果排除了系统权限以及 Javascript 权限问题,则很大概率是上述问题。其实,Keyboard Maestro 官方已经 发布了 这一提示,而 Keyboard Maestro 论坛上也至少有一打的贴子涉及这一问题。
相关讨论:
- Open URL in Safari stopped working - Questions & Suggestions - Keyboard Maestro Discourse
- Safari Macro Group Is Disconnected From Safari After Ventura Update - Keyboard Maestro Discourse
Keyboard Maestro 无法运行命令
许多人发现,自己通过 HomeBrew 安装的第三方命令行工具无法在 Keyboard Maestro 中使用,Keyboard Maestro 会提示找不到命令。
原因在于,Keyboard Maestro 中的环境与 Terminal 并不相同,不加指示地下达命令,自然会令 Keyboard Maestro 无法理解。有很多对 Keyboard Maestro 本身动手术的方法,但我更喜欢把影响限制在某个出问题的 Macro 自身,而不会轻易触及整个 Keyboard Maestro。
我的办法很简单,先找到无法运行的命令行工具在哪里,然后在 Keyboard Maestro 中换上完整命令路径。例如图像处理工具 imagemagick 有个常用命令 convert
,可以先在 Terminal 中运行 which convert
,以获得命令的完整路径;接着移步 Keyboard Maestro,将 convert
换成完整的 /usr/local/bin/convert
(注意,你的实际情况可能与我不同)。
LaunchBar 相关问题
LaunchBar 是一款 macOS 下的老牌启动器工具。
基于 AppleScript 的脚本没有实时反馈
大约两三个大版本系统前开始,LaunchBar 中基于 AppleScript 的自动化动作无法实时反馈结果,每次调整关键词时后需重新打开 LaunchBar 窗口才能生效。目前没有找到治本的方法。如果您有一定的动手能力,可以尝试将 AppleScript 脚本嵌入 Python,从而绕过此问题。以 Python3 为例,调用 AppleScript 的基本代码模板如下(在具体例子中请注意输入输出的格式):
from subprocess import Popen, PIPE
scpt = '''
on run {x, y}
return x + y
end run'''
args = ['2', '2']
p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt.encode('utf-8'))
stdout.decode('utf-8')
print (p.returncode, stdout, stderr)
参考案例:《用LaunchBar填上Finder窗口管理的空白》、《标签页级高精度窗口管理(LaunchBar 为例)》。
无法获得任何输入
部分情况下,在 LaunchBar 运行任何自动化动作都会要求提供输入,即便你已经输入;或者,你输入的文字被无视,只留下空白或默认文本。根据经验,此问题多见于运行自动化动作报错后或修改过自动化动作后。
请退出 LaunchBar 并重启之。
HTML 相关问题
为什么中文有乱码
症状:HTML 渲染成网页后出现,中文部分为乱码,而西文部分则正常。常见于网页剪藏、Markdown 转换生成 HTML、扒取网页源码等场景。
尝试:该问题通常是编码方式不正确导致的。多数现代浏览器会自动编码中文,但在自动化环境中,很多工具不一定像浏览器那样面面俱到,包括声名显赫的 DEVONthink 也没有对中文专门适配。如确实是编码问题,则解决方案也很简单,在 HTML 文件头部(<head>
标签内部)加上如下代码即可,该代码表示用 utf-8 编码 HTML,此时一般就能正常显示中文。
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
GitHub 相关问题
我所编写的几乎所有自动化资源,都会公布在 GitHub 上,对此行为有必要做一番解释,并提供下载方法。
为什么用 GitHub 分享自动化动作?
开源是一种意识形态,无论是希望帮助更多人,还是想要别人帮忙改进代码,开源恐怕都是最佳途径。而 GitHub 则是当前最成熟的开源途径之一,相比其他更加 geek 的方法,也相对容易上手,纯粹想要下载资源而不懂编程的读者,同样可以使用。
当然,用 GitHub 分享自动化资源,其实也方便我自己管理,只需按一颗快捷键,即可同步本地文件到网上,非常省力。
如何下载 GitHub 上的资源?
GitHub 和我们传统认识上的“下载站点”不同,你一般不能点击一次就下载某个软件(除非发布者专门放出了下载版),通常只能把别人的仓库(repo)整个下载下来。这一设计的目的是明显的:把源代码交给您,鼓励您参与开发或排错,而不是拿来主义,只取走一个可用的最终版本。
不过,毕竟不是每个人都有时间从事开发,您很可能只需要一个脚本,而我的仓库中有几百个动作,显然没有必要全部下载。有很多方法可以让您直接下载某个特定文件,这里推荐一个 Bookmarklet(小书签)版本。将 这个 链接拖到网址收藏夹,然后在想要下载的 GitHub 页面上点击一下,就可以把文件下载到本地。
注意,上述 Bookmarklet 背后其实挂上了一个服务,而在线服务随时可能失效。如果它真的失效了,请参考《如何下载 GitHub 中的脚本文件》,尝试更为传统也更可靠的方式;或搜索 下载 GitHub 文件
,以获得其他方法。
- 20241030 更新:LaunchBar 的输入问题。
- 20231215 更新:增加 AppleScript 相关内容。
- 20231024 更新:关联 xcrun error 相关文章。
- 20230814 更新:Shortcuts 无法从列表所选项(Choosen Item)中获取数据。