VPN 工具设置:启动时的环境,还是钩子内的导出?
钩子只启动它自己的子进程,影响不到你已经打开的终端。启动时的环境让私有端点只出现在真正需要它的那一条命令上。
导出 API 端点的 VPN 钩子改变的是它启动的那些进程的环境,而不是隧道建立时已经打开的那个终端。正是这一处区别,解释了大多数「工具仍在调用公共端点」的报告。设置有两个可行的放置位置,选哪个取决于谁来使用它、它多久变一次。在再加一个启动脚本之前,先把两者比较清楚。
设置可以放置的两个位置
第一种是在命令本身前面加前缀:值只属于那一次调用,随调用结束而消失。第二种是在连接钩子里导出,它会覆盖钩子此后启动的每一个进程。两者的差别在作用范围和生命周期上,而不在写法上,这个差别决定了大多数故障。
| Property | Prefix on the command | Export from the hook |
|---|---|---|
| Who receives it | That invocation only | Children the hook starts |
| Lifetime | Until the process exits | Until the hook's own session ends |
| Leakage | Scoped to one command | Applies to later commands in that session |
| Repeat cost | Every invocation | Once per connection |
| Works for an open editor | No, unless the editor is started with it | No |
表格让钩子看起来便宜,却藏起了真正的账单:它也会给与任务无关的命令选中私有端点。请把每一行当成约束而不是偏好。如果端点按任务变化,前缀在精确性上胜出,哪怕要多敲一次键。
为什么钩子够不到已经打开的终端
环境变量在进程映像创建时交给进程。在连接之前启动的终端保留着它拿到的那一份副本,而在钩子里执行的导出并不是向机器上每个进程广播。只有钩子自己的子进程会继承它。终端自己的子进程取的是它们启动那一刻终端持有的内容,所以同一条命令可以在一个终端里成功,在另一个里失败。
图形编辑器同样如此。它的扩展宿主、内置终端和后台语言服务器在启动时就已经分叉,各自持有副本。重新打开文件夹并不一定会重启这些子进程,所以你加上的设置依然到不了它们。
最省事的验证,是从失败的地方打印这个变量,而不是从能用的终端里打印。如果失败的进程是在隧道之前启动的,这次导出从一开始就没有机会。
按命令使用的写法
把设置写成前缀,选择就留在使用它的命令里,端点在不同任务间变化时这一点很有用:
env INTERNAL_API='https://internal-api.example.net:8443' my-work-tool
这条命令只是示例:my-work-tool 是占位符,INTERNAL_API 也不是 VPN 的标准,请换成你真正运行的程序的文档化设置,以及你自己批准的主机。不要把令牌或密码写在同一行,它们会留在终端历史里。
当多条命令属于同一项任务时,用一个经过审阅的短包装脚本先设置变量,再启动它们。这样只保留一处定义,又不会把这个值变成终端里后续每条命令的全局设置。
重新加载、重启,还是放着不动
对已经在运行的工具,优先用它自己的重新加载或工作区配置。否则先保存工作,再重启真正读取该设置的那个组件——它往往是语言服务器,而不是编辑器窗口。只重启窗口、假定子进程也跟着重启,正是重新加载看起来不生效的原因。
断开连接是另一件事。暂停、关闭或重连属于应用自己的逻辑,端点变量并不控制它。把这个变量当作选择地址的配置,而不是规定之后允许使用哪些网络流量的规则,两件事就可以分开处理。