命令行
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
结合使用时,这在实践中最有利。