命令行
使用 groupshelf 命令,可以在“终端”或脚本中将打开的窗口分组、向组中添加窗口或解散组,以及列出窗口。GroupShelf 1.3.0 及更高版本附带此命令。
安装
该命令包含在 GroupShelf.app 中。安装它,就是在 PATH 中的某个文件夹里创建指向它的链接。
如果使用 Homebrew,安装 GroupShelf 时会自动为你链接该命令:
brew install --cask alpharium-tech/tap/groupshelf如果你在 1.3.0 之前通过 Homebrew 安装了 GroupShelf,在 App 内更新不会添加该链接。请运行一次以下命令:
brew reinstall --cask groupshelf如果不使用 Homebrew,GroupShelf 的设置 › 命令行会显示创建链接的命令,可直接拷贝。在“终端”中运行它,系统会要求输入你的 Mac 密码。对于“应用程序”文件夹中的 GroupShelf,命令如下:
sudo mkdir -p /usr/local/bin && sudo ln -sf '/Applications/GroupShelf.app/Contents/Helpers/groupshelf' /usr/local/bin/groupshelf只有当 GroupShelf 位于“应用程序”文件夹并从那里打开时,设置中才会提供该命令:指向“下载”文件夹中副本的链接会在 App 移动后失效。
安装完成后,设置 › 命令行会显示它的安装位置,运行 groupshelf version 会显示它所属的 GroupShelf 的版本。
启用
操作窗口的命令只有在你允许后才能使用:在 GroupShelf 的设置 › 命令行中,打开“允许通过命令行和脚本控制”。在你打开之前,它一直处于关闭状态。help 和 version 无论开关与否都可以使用。
打开期间,你允许控制 GroupShelf 的 App(例如终端 App)及其中运行的任何程序,都可以将窗口分组,并读取此桌面上所有窗口的标题。
权限
首次使用时,macOS 会询问是否允许你的终端 App 控制 GroupShelf,命令会等待你的回答。如果你选择了不允许,请在系统设置 › 隐私与安全性 › 自动化中,打开你的终端 App 下的 GroupShelf。
Visual Studio Code
VS Code 的 Universal 版本(大多数人下载的版本,1.104 及更高版本)缺少 macOS 询问此权限前所需的条目。macOS 会不加询问直接拒绝,也不会在 Visual Studio Code 下列出 GroupShelf,因此 groupshelf 会让 macOS 照常询问。它会显示下面这行,对话框中会出现 Visual Studio Code 的名称:
groupshelf: asking macOS whether your terminal app may control GroupShelf…
回答一次后,之后就能一直使用。如果在“自动化”中 Visual Studio Code 下仍未列出 GroupShelf,请改为安装 VS Code 的 Apple silicon 或 Intel 版本,而不是 Universal 版本:这两个版本都带有该条目。Homebrew 的 visual-studio-code cask 会安装适合你 Mac 芯片的版本。
指定窗口
命令中凡是接受 <window> 的地方,都可以用以下三种方式之一来写。含有空格的内容请加上引号。
- App
它的一个窗口:该 App 中处于活跃状态的窗口,否则为最前面的窗口。可以用程序坞中显示的名称或文件名(不区分大小写)来指定 App,也可以用它的 Bundle ID 或路径。Safari"Visual Studio Code"com.apple.Safari/Applications/Safari.app - App 加标题的一部分
该 App 中标题包含这段文本的窗口,不区分大小写。Code:proj-a"Terminal:my server" - 窗口 ID
groupshelf list显示的数字。
将一个 App 写两次,即可使用它的两个窗口。
如果一个标题符合多个窗口,就会出错,除非你加上 --frontmost(使用其中最前面的窗口)或 --all(全部使用)。对于未指定标题的 App,--all 也会使用它的所有窗口。
groupshelf 从不打开 App,因此 App 必须已在运行。group 和 add 会等待正在运行的 App 的窗口出现,最长 30 秒,所以刚刚打开的 App 也能使用:
open -a Safari && open -a Terminal && groupshelf group Safari Terminal只有此桌面上的窗口才算在内,包括最小化的窗口。全屏幕窗口有自己的桌面,因此不算在内。
相对路径以当前文件夹为基准。若要给路径加上标题,请写在 .app: 之后,例如 /Applications/Safari.app:Docs。
命令
groupshelf help 会列出所有命令,groupshelf help <command> 会说明其中一个。如果 GroupShelf 未在运行,命令会在后台启动它,但绝不会打开你指定的 App。
选项可以放在 -- 之前的任何位置,其值跟在空格或 = 之后:--name Work 或 --name=Work。名称以 - 开头的 App 请放在 -- 之后。
group
groupshelf group [--name <name>] [--all | --frontmost] <window> <window>...
按指定的顺序将窗口合并为一组标签页。第一个窗口决定组的位置和大小,完成后会显示它的标签页。已在其他组中的窗口会离开原来的组,加入这个组。
至少需要两个窗口,使用 --all 时一个 <window> 即可。如果有窗口在 30 秒内没有出现,就用其余窗口组成组,并报告缺少的窗口。对正好由这些窗口组成的组运行时,只会按指定顺序排列标签页。
--name <name>- 为新组命名,以便之后用
--group找到它。 --frontmost- 当一个标题符合多个窗口时,使用最前面的那个。
--all- 使用所有符合的窗口:App 的所有窗口,或包含该标题的所有窗口。
groupshelf group Safari Terminal Notes Mailgroupshelf group --name Work Code:proj-a Terminal:proj-a Safariopen -a Safari && open -a Terminal && groupshelf group Safari Terminalgroupshelf group --all Terminal
add
groupshelf add [--all | --frontmost] --group <name> <window>... groupshelf add [--all | --frontmost] <member> <window>...
将窗口添加到此桌面上某个现有组的末尾,该组的位置、大小和显示的标签页保持不变。已在其他组中的窗口会移过来。与 group 一样,只使用已打开的窗口,最长等待 30 秒。
用 --group 指定组,或用组中的一个窗口来指定(<member>,写法与 <window> 相同)。App,或带 --frontmost 的标题,会优先使用组中还没有的窗口;已在组中的窗口保持不变。
--group <name>- 按名称指定的组,不区分大小写:即通过
--name设定的名称,或右键点按其标签页栏后选择“命名组…”设定的名称。 --frontmost- 当一个标题符合多个窗口时,使用最前面的那个。
--all- 使用所有符合的窗口:App 的所有窗口,或包含该标题的所有窗口。
groupshelf add --group Work Slackgroupshelf add Code:proj-a Terminal:proj-a
detach
groupshelf detach [--all | --frontmost] <window>...
将窗口从所在的组中分离;只剩一个窗口的组会解散。不会打开任何东西,也不会等待:窗口必须已在此桌面上。不在任何组中的窗口保持不变。
--frontmost- 当一个标题符合多个窗口时,使用最前面的那个。
--all- 使用所有符合的窗口:App 的所有窗口,或包含该标题的所有窗口。
groupshelf detach Slackungroup
groupshelf ungroup [--group <name>]... [<member>]...
解散组,窗口留在原处。用 --group 指定组(多个组就重复使用),或用组中的一个窗口来指定(<member>,写法与 <window> 相同)。不在任何组中的窗口会被跳过。只要有一个找不到,就不会解散任何组。
--group <name>- 按名称指定的组,不区分大小写:即通过
--name设定的名称,或右键点按其标签页栏后选择“命名组…”设定的名称。
groupshelf ungroup --group Workgroupshelf ungroup Code:proj-a
list
groupshelf list
按从前到后的顺序列出此桌面上可以分组的窗口,最小化的窗口排在最后。GroupShelf 自己的窗口和被排除的 App 的窗口不会列出。每行对应一个窗口,包含以下以制表符分隔的字段,没有标题行:
- 窗口 ID
- App 名称
- 标题
- 组编号(没有则为空)
- 组名称(没有则为空)
minimized(未最小化则为空)
groupshelf list4211 Safari GroupShelf — Command line 1 Work4198 Terminal proj-a — zsh 1 Work4305 Mail Inbox3977 Notes Shopping minimized
标题中的制表符或换行符会变成空格,因此字段始终对齐。ID 可以用作其他命令的 <window>;配合 fzf,可以挑选窗口并将它们分组:
groupshelf list | fzf -m | cut -f1 | xargs groupshelf grouphelp
groupshelf help [<command>]
显示命令列表,或其中一个命令的用法:group、add、detach、ungroup 或 list。
groupshelf help groupversion
groupshelf version
显示命令所附带的 GroupShelf 的版本和构建号。两者始终是同一个构建。
退出状态
脚本可以根据退出状态进行分支处理。消息会输出到标准错误,并且都以 groupshelf: 开头。
0- 成功。
1- GroupShelf 报告了错误:需要修改请求,例如某个 App 没有在运行。缺少部分窗口而组成的组也算在内。
2- 用法错误:命令行本身有误。命令会说明错在哪里并显示其用法,不会联系 GroupShelf。
3- 无法联系 GroupShelf:需要修正设置,例如缺少某项权限。
疑难解答
每条消息的含义及处理方法。其中的名称和数字只是示例,实际会显示你输入的内容。
联系 GroupShelf · 退出状态 3
groupshelf: GroupShelf.app not found
命令找不到它所附带的 GroupShelf:它是存放在 App 之外的副本,并且没有安装 GroupShelf。请安装 GroupShelf,然后按照“安装”中的方法链接该命令,而不是拷贝它。
groupshelf: GroupShelf could not be launched: <reason>
GroupShelf 没有在运行,macOS 也因所示原因无法打开它。请自行打开 GroupShelf,然后再次运行该命令。
groupshelf: GroupShelf did not start within 15 seconds
GroupShelf 已在后台打开,但没有及时准备就绪。请再次运行该命令。
groupshelf: GroupShelf did not answer in time; if macOS asked whether your terminal app may control GroupShelf, answer that and try again
这通常是因为 macOS 仍在等待你回答权限询问。请回答后再次运行该命令。
groupshelf: not allowed to control GroupShelf; allow your terminal app in System Settings › Privacy & Security › Automation
你的终端 App 不能控制 GroupShelf。请在系统设置 › 隐私与安全性 › 自动化中,打开你的终端 App 下的 GroupShelf。
groupshelf: if Visual Studio Code doesn't list GroupShelf there, install VS Code's Apple silicon or Intel build; its Universal build can't ask macOS for this permission
在 VS Code 的终端中,这一行会紧接在上一行之后出现。请参阅“权限”中的 Visual Studio Code 部分。
groupshelf: this version of GroupShelf doesn't support groupshelf; update GroupShelf
命令联系到的 GroupShelf 早于该命令,例如 Mac 上其他位置的旧副本。请将 GroupShelf 更新到 1.3.0 或更高版本,并删除所有旧副本。
groupshelf: could not reach GroupShelf (error <number>)
macOS 因其他原因无法传递请求;数字是它的错误代码。请退出并重新打开 GroupShelf,然后重试。如果问题持续出现,请带上该数字联系支持。
GroupShelf 的设置和状态 · 退出状态 1
groupshelf: control from the command line is off; turn on "Allow control from the command line and scripts" in GroupShelf Settings › Command Line
按照“启用”中的说明,打开设置 › 命令行中的开关。
groupshelf: GroupShelf needs Accessibility access; allow it in System Settings › Privacy & Security › Accessibility
没有该权限,GroupShelf 就无法移动窗口。请在系统设置 › 隐私与安全性 › 辅助功能中打开 GroupShelf。
groupshelf: GroupShelf is paused while Stage Manager is on
GroupShelf 不能与台前调度同时使用。请在系统设置中关闭台前调度,然后重新启动 GroupShelf。
groupshelf: GroupShelf hasn't finished starting; try again
请稍等片刻后再次运行该命令。
groupshelf: another group request is still running
GroupShelf 一次只处理一个请求,而 group 和 add 可能会等待窗口最长 30 秒。请在另一个请求完成后再次运行。
groupshelf: "Slack" is excluded from grouping in GroupShelf settings
该 App 位于设置 › 分组中的“排除的 App”里。若要将它的窗口分组,请从那里移除它。
指定窗口 · 退出状态 1
groupshelf: "Safari" isn't running; open it first — groupshelf only works with windows already open
请先打开该 App。之后 group 和 add 会等待它的窗口出现,最长 30 秒。
groupshelf: no application named "Safary"
请检查拼写。未在运行且不在“应用程序”文件夹中的 App,只能用它的 Bundle ID 或路径来指定。
groupshelf: "/Applications/Utilities" is not an application
该路径指向的不是 App。请让它指向 .app 本身。
groupshelf: "Terminal:proj" fits 2 windows ("proj-a — zsh", "proj-b — zsh"); give more of the title, a window ID from groupshelf list, or --frontmost or --all有多个窗口的标题包含这段文本。请用消息中列出的方法之一缩小范围。
groupshelf: no window 4211 on this desktop; groupshelf list shows the windows there
该窗口已关闭,或在另一个桌面上,或处于全屏幕状态。请运行 groupshelf list 查看当前的 ID。
groupshelf: no window for "Slack" on this desktop
detach、ungroup 和 <member> 只看此桌面上已有的窗口,不会等待。请确认该窗口在这里是打开的。
groupshelf: "4211" names a window another argument already names
有两个参数指向同一个窗口。请删除其中一个。
groupshelf: GroupShelf can't group its own windows
请不要在命令中指定 GroupShelf。
指定组 · 退出状态 1
groupshelf: no group named "Work"
没有组使用这个名称。groupshelf list 的第五个字段会显示每个窗口所在组的名称。
groupshelf: --group "Work" fits 2 groups; name the group by one of its windows instead
有多个组使用这个名称。请改用组中的一个窗口作为 <member> 来指定该组。
groupshelf: the group of "Work" isn't on this desktop
add 只能向此桌面上的组添加窗口。请前往该组所在的桌面,在那里运行。
groupshelf: "Safari" isn't in a group; groupshelf group makes one
作为 <member> 指定的窗口不在任何组中。请用 group 创建一个组。
部分完成 · 退出状态 1
groupshelf: grouped 3 windows; no window for "Mail" on this desktop within 30 seconds groupshelf: added 1 window; no window for "Mail" on this desktop within 30 seconds groupshelf: nothing added; no window for "Mail" on this desktop within 30 seconds
第一个分号之前的内容已经完成。分号之后列出的窗口没有包括进来:它们在 30 秒内都没有出现在此桌面上。
groupshelf: no group created: only 1 window to group; no window for "Mail" on this desktop within 30 seconds
找到的窗口不足两个,因此没有做任何更改。
groupshelf: grouped 2 windows; "Mail" could not be added to the group
该窗口所在的组或它要加入的组已被锁定。请右键点按被锁定的组的标签页栏,选择“解锁组”,然后再次运行该命令。
用法错误 · 退出状态 2
groupshelf: unknown option '--names' Usage: groupshelf group [--name <name>] [--all | --frontmost] <window> <window>... Run 'groupshelf help group' for more.
命令行本身有误:第一行说明错在哪里,后面是该命令的用法。没有向 GroupShelf 发送任何内容。