为什么要以 root 切换用户身份运行“npm run <script>”?

Kic*_*csi 9 root npm npm-scripts

我在高山图像 ( node:16-alpine) 中设置了一个新项目,/app2结构如下:

- node_modules
  - .bin
    - dummy
- package.json
Run Code Online (Sandbox Code Playgroud)

包.json:

{
  ...
  "scripts": {
    "dummy": "dummy",
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)

假的:

#!/usr/bin/env node

setInterval(() => console.log("."), 1000)
Run Code Online (Sandbox Code Playgroud)

现在,当我使用npm run dummyroot 用户而不是 root 用户运行时,节点命令将使用拥有项目根目录的任何用户运行。例如:

/app2 # ls -lah
...    
drwxr-xr-x    3 node2    node        4.0K Jan 17 08:27 .
...

/app2 # whoami
root

/app2 # npm run dummy
...

# in a different terminal:
/app2 # ps x
...
  816 root      0:00 npm run dummy
  827 node2     0:00 node /app2/node_modules/.bin/dummy
...
Run Code Online (Sandbox Code Playgroud)

su node && npm run dummy如果我不使用 root 运行 npm (例如:将以用户身份运行node,而不是node2),则不会发生这种情况。

为什么是这样?有谁知道这是否记录在任何地方?或者如何以 root 身份运行脚本?(我知道不推荐这样做,但它位于 docker 容器内并且仅用于开发)

Rom*_*nka 21

这发生在@npmcli/promise-spawn

 const isRoot = process.getuid && process.getuid() === 0
 const { uid, gid } = isRoot ? inferOwner.sync(cwd) : {}
Run Code Online (Sandbox Code Playgroud)

您找不到文档,因为此行为不久前已被删除

这是该提交中删除的旧注释,描述了您看到的行为:

注意:当当前用户是 root 时,这将用于 infer-owner查找当前工作目录的所有者,并使用该有效的 uid/gid 运行。否则,它始终以当前用户身份运行。(这有助于防止进行 git checkout 等操作,并将 root 拥有的文件留在用户拥有的位置。)

  • 非常感谢,看来 npm cli 一直在使用这个包的旧版本(截至目前,npm cli 8.4.0 使用promise-spawn 1.3.2),其中包括这个魔法 (7认同)