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具有ps
setuid 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 中设置的极少数情况,这可能仍然是唯一的方法。
我赞成第一个选项(如果有其他贡献的话,在选择答案之前仍在等待)。