从另一个进程获取 shell 的未解析 pwd

从另一个进程获取 shell 的未解析 pwd

我是遇到问题我需要获取 shell 进程的未解析的符号链接。例如,给定一个符号链接~/link-> ,如果 bash 使用of~/actual启动,我需要从 bash 进程外部获取它。$PWD~/link

得到解决cwd 可以使用lsof/proc中调用的https://unix.stackexchange.com/a/94359/115410但我开始认为不可能得到未解决的小路。

我尝试过使用lsof -b而不使用readlink,但日志记录表明该路径无论如何都不会尝试使用readlink。似乎确实可以通过/proc/.../environ并解析来读取环境PWD,但这很慢,/proc系统上可能不存在,并且我相信尝试读取进程的环境会存在一些安全隐患。

这是我试图修复的有问题的代码:

lsof在 macOS 上:

exec('lsof -OPln -p ' + this._ptyProcess.pid + ' | grep cwd', (error, stdout, stderr) => {
  ...
});

/proc在Linux上:

Promises.readlink(`/proc/${this._ptyProcess.pid}/cwd`);

答案1

当前工作目录的逻辑值(逻辑cwd,也就是你所说的“未解析的pwd”)是shell的内部概念,而不是内核的概念。内核只记住完全解析的路径(物理cwd)。因此您无法通过通用系统接口获得所需的信息。你必须得到shell的配合。

环境PWD变量是 shell 如何将逻辑 cwd 传输到其子进程的方式。当一个 shell 运行另一个 shell 时,父级设置PWD为逻辑 cwd(每当运行程序时都会执行此操作),子级检查PWD的值PWD是否合理,如果是,则使用它作为其逻辑 cwd,回退到物理 cwd。 cwd 如果$PWD丢失或错误。

观察:

#!/bin/sh
mkdir /tmp/dir
ln -sf dir /tmp/link
cd /tmp/link
sh -c 'echo Default behavior: "$PWD"'
env -u PWD sh -c 'echo Unset PWD: "$PWD"'
PWD=/something/fishy sh -c 'echo Wrong PWD: "$PWD"'
rm /tmp/link
rmdir /tmp/dir

输出:

Default behavior: /tmp/link
Unset PWD: /tmp/dir
Wrong PWD: /tmp/dir

读取进程的环境不会产生任何特定的安全影响,但它告诉您PWD进程启动时的值是什么。如果处理后更改为另一个目录,则环境中的值不再相关。您需要的是如果 shell 现在运行另一个进程的话环境中的值。但出现这种情况的唯一方法是实际使 shell 运行另一个进程。

GUI 查找其运行的 shell 的 cwd 的典型方法是让 shell 将其打印出来。如果您偶尔需要这些信息并希望将 shell 配置的最大控制权留给用户,请确保 shell 显示提示并发出命令pwd。这很简单,即使在“异国情调”的 shell(如 csh 和 Fish)中也能工作,但在极端情况下(例如包含换行符的目录名称)是不明确的。如果可以调整 shell 配置,您可以让 shell 在每次显示提示时(PS1对于许多 shell,但使其包含当前目录的方法各不相同)或更改目录时(chpwd_functions在 zsh 中)打印转义序列,在其他 shell 中更具侵入性的方式)。

请注意,如果逻辑 cwd 的组件已被移动或删除,或者符号链接已更改为指向其他位置,则该值可能是错误的。另一方面,物理 cwd 始终是正确的。 (如果该目录已被删除,Linux 的,即所有程序(例如和 )获取其信息的位置,将显示为一个损坏的符号链接,其目标以 结尾。我不知道macOS 上关于已删除的当前目录的报告。)如果您确实找到了逻辑 cwd,您可能应该确保它与物理 cwd 匹配,如果不匹配,则回退到物理 cwd。/proc/PID/cwdpslsof(deleted)lsof

相关内容