命令行

使用 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 写两次,即可使用它的两个窗口。

如果一个标题符合多个窗口,就会出错,除非你加上 --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 Slack

ungroup

groupshelf ungroup [--group <name>]... [<member>]...

解散组,窗口留在原处。用 --group 指定组(多个组就重复使用),或用组中的一个窗口来指定(<member>,写法与 <window> 相同)。不在任何组中的窗口会被跳过。只要有一个找不到,就不会解散任何组。

选项
--group <name>
按名称指定的组,不区分大小写:即通过 --name 设定的名称,或右键点按其标签页栏后选择“命名组…”设定的名称。
示例
groupshelf ungroup --group Workgroupshelf ungroup Code:proj-a

list

groupshelf list

按从前到后的顺序列出此桌面上可以分组的窗口,最小化的窗口排在最后。GroupShelf 自己的窗口和被排除的 App 的窗口不会列出。每行对应一个窗口,包含以下以制表符分隔的字段,没有标题行:

  1. 窗口 ID
  2. App 名称
  3. 标题
  4. 组编号(没有则为空)
  5. 组名称(没有则为空)
  6. minimized(未最小化则为空)
groupshelf list4211	Safari	GroupShelf — Command line	1	Work	4198	Terminal	proj-a — zsh	1	Work	4305	Mail	Inbox			3977	Notes	Shopping			minimized

标题中的制表符或换行符会变成空格,因此字段始终对齐。ID 可以用作其他命令的 <window>;配合 fzf,可以挑选窗口并将它们分组:

示例
groupshelf list | fzf -m | cut -f1 | xargs groupshelf group

help

groupshelf help [<command>]

显示命令列表,或其中一个命令的用法:group、add、detach、ungroup 或 list。

示例
groupshelf help group

version

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 发送任何内容。

← 返回首页