`/proc/$PID/cwd` :是否有 POSIX 等效项?

`/proc/$PID/cwd` :是否有 POSIX 等效项?

Linux 有一个/proc目录和文件系统,据我所知,它们不是 POSIX 的一部分。在每个/proc/$PID子目录中,都有一个符号链接 ,cwd指向该 PID 进程的实际工作目录(该cwd链接始终是最新的)。

此符号链接对于某些用例很方便,例如使用不同的 shell 以及在两个 shell(正式地,它们的工作目录)之间交换文件。

有没有一种简单的方法可以仅使用 POSIX 功能来获得类似的东西?

有关问题的更多信息

发表评论后,更精确:它不一定是链接和环境变量 lile $<PID>_CWD,也很好,尽管乍一看,我不相信存在这样的解决方案。它必须易于引用(例如符号链接或环境变量),并且每次其他进程切换其工作目录时始终保持最新。

解决方案不一定是POSIX,最重要的方面是可移植性,但POSIX肯定是一个保证。

答案1

我有一个使用lsof.默认情况下,它没有安装在 BSD 上,因此如果有人想在 BSD 上使用它,则需要安装它。

制作一个shell脚本:

#!/bin/sh
lsof -p $1 | grep cwd | awk '{print $9}'

将其复制到您的路径中的目录中。它打印第一个参数 IE 中给出的 PID 的工作目录

$ script 1987
/home/enedil

答案2

POSIX 在获取有关不相关进程的信息方面没有提供太多功能。只有ps,真的,它没有提供有关当前目录的任何信息。 C 级 API 也好不到哪儿去(事实上,大多数检索到的信息ps只能通过解析其输出来检索)。

有趣的是,POSIX 确实提供了一种可移植的方式来进行相反的操作:给定一个文件,您可以通过调用来找出哪些进程打开了该文件fuser。以下代码段列出了具有特定工作目录的进程的 PID:

fuser -f "$directory_name" 2>&1 | sed -e '$!d' -e 's/.*://' -e 's/  */\
/' | sed -n 's/c$//p'

如果您希望以实践中可移植的方式获取有关流程的信息,请使用拉索夫。 lsof 的作者已经完成了实现在不同 UNIX 变体上检索信息的所有不同方法的工作。

对于休闲浏览:

lsof -a -p "$pid" -d cwd

对于自动解析:

lsof -a -p "$pid" -d cwd -F n | sed -e '1d' -e '2s/^n//'

请注意,lsof用字符串替换换行符\n

某些 Unix 变体提供了不需要第三方软件的方法,但这些方法将强制特定于每个变体。在一个非常相关的注释中,请参阅文件描述符链接的可移植性

一些旧的unices具有pssetuid root并读取内核内存,因此使用setuid二进制文件是获取此信息的唯一方法。

答案3

我将贡献我自己的答案。

/proc/$PID/cwd在交互式 shell 的上下文中(问题集中在这个上下文上),一个选项可以是使用 Bash 提供的自动化机会自动维护链接:

PROMPT_COMMAND="ln -sfT \$(pwd) ~/$LINK_NAME"

f选项是必需的,因为该链接会经常被覆盖。该T选项是必需的,否则该f选项似乎可以正常工作。

可以使外壳合作,例如使用此~/.bashrc

if [ -v CWD_LINK_NAME ]; then
   PROMPT_COMMAND='ln -sfT "$(pwd)" "'$CWD_LINK_NAME'";'$PROMPT_COMMAND
   declare -r CWD_LINK_NAME
   function rm_cwd_link() {
      rm "$CWD_LINK_NAME"
   }
   trap rm_cwd_link EXIT
fi

可以将 shell 或终端设置为CWD_LINK_NAME任何相关值来执行。前任。CWD_LINK_NAME="~/$SOME_ROLE_NAME" gnome-terminal

另一种选择是使用相同的概念来跟踪变量中的 pear 工作目录,这种跟踪基于两者@吉尔斯@nedil贡献:

PROMPT_COMMAND="PEAR_WD=\$(lsof -p $PID | awk '/cwd/{print \$9}')"

$PROMPT_COMMAND然而,这不太准确且不太方便,但对于无法在其他 shell 中设置的极少数情况,这可能仍然是唯一的方法。

我赞成第一个选项(如果有其他贡献的话,在选择答案之前仍在等待)。

相关内容