跳到主要内容

命令行

watchman 可执行文件包含 watchman 服务的客户端和服务器组件。

默认情况下,当运行 watchman 时,它会尝试与您现有的服务器实例(每个用户都有自己的持久进程)进行通信,如果该实例不存在,它将尝试启动它。

有一些选项会影响 watchman 如何定位服务器,一些选项仅影响客户端,还有一些选项仅影响服务器。由于所有选项都由同一个可执行文件理解,因此我们将这些选项分成单独的部分,以便更清楚地了解它们何时适用。

关于默认位置的快速说明

Watchman 将优先从 $USER 环境变量解析您的用户名,如果 $USER 未设置,则从 $LOGNAME 解析。如果两者都未设置,watchman 将使用 getpwuid(getuid()) 从系统查找。当我们在本文档中提到 <USER> 时,我们指的是此解析的结果。

在某些情况下,Watchman 需要在临时位置创建文件。 Watchman 将通过查看 $TMPDIR 环境变量来解析此临时位置,如果 $TMPDIR 未设置,则查看 $TMP 。如果两者都未设置,watchman 将使用 /tmp。当我们在本文档中提到 <TMPDIR> 时,我们指的是此解析的结果。

Watchman 在一个位置跟踪其持久状态,我们在本文档中将其称为 <STATEDIR>

自 3.1 起。

STATEDIR 默认为 <PREFIX>/var/run/watchman。您可以使用配置选项 --enable-statedir 在构建 watchman 时更改此默认值。

早期版本的 Watchman 没有默认的 statedir,而是使用 <TMPDIR> 作为此状态。我们不再使用它,因为某些环境会随机化 <TMPDIR> 位置,这使得客户端难以定位 Watchman 服务。

自 3.8 起。

STATEDIR 默认为 <PREFIX>/var/run/watchman/<USER>-state。您可以使用配置选项 --enable-statedir 在构建 watchman 时更改此默认值; 配置选项替换此字符串的 <PREFIX>/var/run/watchman 部分。如果您指定 --disable-statedir,那么字符串的该部分将从 <TMPDIR> 位置计算得出。

如果 <USER>-state 部分不存在,Watchman 将创建它,并将执行一些权限和所有权检查,以降低不受信任的用户将文件放置在此位置的风险。如果这些检查未通过,watchman 将拒绝启动。

定位服务

 -U, --sockname=PATH   Specify alternate sockname

sockname 的默认位置将是 <STATEDIR>/<USER>。根据配置方式,旧版本的 Watchman 默认使用 <TMPDIR>/.watchman.<USER>

如果您正在构建客户端以编程方式访问服务,我们建议您调用 watchman get-sockname 以发现客户端和服务器将使用的路径。如果服务尚未运行,这会产生为您启动服务的副作用。

客户端选项

如果在上面指定的 socket 上没有响应,watchman 可执行文件将尝试启动服务。在某些情况下,如果服务没有运行,最好避免启动服务

 --no-spawn            Don't spawn service if it is not already running.
Will try running the command in client mode if
possible.
--no-local When no-spawn is enabled, don't use client mode

客户端模式实现 watchman find command 作为立即搜索。

这些选项控制客户端如何与服务器通信

 -p, --persistent           Persist and wait for further responses
--server-encoding=ARG CLI<->server encoding. json or bser.

持久连接在 CLI 中的使用相对有限,但可以用于临时连接到服务以接收日志信息(请参阅 log-level)。

服务器编码选项控制与服务器通信时请求和响应的格式。您通常不必担心这一点。

输入和输出

CLI 的大多数简单调用都将传递参数列表

$ watchman watch /path/to/dir

这被转换为如下请求

["watch", "/path/to/dir"]

并使用 Socket 接口 发送到服务。

接收到响应,然后根据选定的输出编码将其格式化后发送到 stdout

     --output-encoding=ARG  CLI output encoding. json (default) or bser
--no-pretty Don't pretty print JSON output (more efficient
when being processed by another program)

每个命令都有自己的响应输出,但如果请求的某些内容不成功,watchman 将始终包含一个名为 error 的字段。如果发生某些协议级别的错误(例如:连接已终止),则不会在 stdout 上打印响应,而是将非结构化的错误消息打印到 stderr,并且进程将以非零退出状态退出。

您可以将 JSON 表示形式发送到 stdin 流,而不是将请求作为命令行参数传递。这些调用都是等效的

$ watchman watch /path/to/dir
$ watchman -j <<-EOT
["watch", "/path/to/dir"]
EOT
$ watchman -j <<< '["watch", "/path/to/dir"]'
$ echo '["watch", "/path/to/dir"]' | watchman -j
$ echo '["watch", "/path/to/dir"]' > cmd.json
$ watchman -j < cmd.json
$ watchman --json-command <<-EOT
["watch", "/path/to/dir"]
EOT

自 3.8 起

现在,当使用 -j 选项时,CLI 还可以识别 BSER 作为有效的输入流。如果尚未将这些选项设置为其他值,这将隐式设置 --server-encoding=bser--output-encoding=bser

退出状态

在大多数情况下,watchman 二进制文件将以返回代码 0 退出; 这表明它生成的输出应该是有效的 JSON。要确定您的命令是否成功,您需要解析 JSON 并查找如上所述的 error 字段。

在发生一些底层错误(例如:连接已终止)的协议级别错误的情况下,watchman 将以非零退出状态退出。

服务器选项

这些选项在启动服务器时使用。客户端可以识别它们,并影响它启动服务器的方式,但如果服务器已经在运行,则不起作用。要更改正在运行的服务器的这些选项的有效值,您需要重新启动它(您可以通过运行 watchman shutdown-server 来停止它)。

默认情况下,如果进程重新启动,watchman 将记住所有监视和相关的触发器并恢复它们。此状态存储在 statefile

 --statefile=PATH      Specify path to file to hold watch and trigger state
-n, --no-save-state Don't save state between invocations

statefile 的默认位置将是 <STATEDIR>/<USER>.state。根据配置方式,旧版本的 watchman 可能会将状态存储在 <TMPDIR>/.watchman.<USER>.state 中。

-o, --logfile=PATH   Specify path to logfile
--log-level set log verbosity (0 = off, default is 1, verbose = 2)

logfile 的默认位置将是 <STATEDIR>/<USER>.log。根据配置方式,旧版本的 watchman 可能会将日志存储在 <TMPDIR>/.watchman.<USER>.log 中。

在某些相对不常见的情况下,例如在测试工具中,您可能需要直接运行服务,而无需将其自身置于后台

 -f, --foreground      Run the service in the foreground

自 4.6 起。

     --inetd                Spawning from an inetd style supervisor

指定此标志后,watchman 将使用 stdin 作为侦听 socket,而不是尝试自行设置它。这允许其他进程维护 socket 并延迟激活 watchman 服务,直到客户端准备好连接。与 systemd 结合使用时,这在实践中最有利。

此提交包含 systemd 的示例配置.