进一步阅读

进一步阅读

jobs调用每个作业时的输出包含工作目录(不一定是每个作业的当前工作目录)是否正确?

$ jobs -l | grep JDBC
[15]  20422 Running   PDFXCview all.pdf &  (wd: ~/mydata/dirlinks/cs/SQL/API/JDBC/general/official/tutorials)
[20]  20542 Running   PDFXCview all.pdf &  (wd: ~/mydata/dirlinks/cs/SQL/API/JDBC/general/wikipedia)

类似地,在中ps,是否可以在调用每个进程时获取其上一个工作目录

在 中pgrep,调用时是否可以在每个进程的前一个工作目录的路径名(字符串)中搜索pgrep ... <pattern_in_working_dir_pathname>

我想在调用进程时通过工作目录中的关键字搜索进程

谢谢。

答案1

命令jobs可能显示程序的工作目录开始了中,如果该目录与 shell 的当前目录不同。这是因为 shell 正在跟踪它所知道的内容(进程开始的位置),而不是当前状态。

它还依赖于外壳。

例如与bash

bash-4.4$ cd /tmp
bash-4.4$ sleep 1000 &
[1] 24807
bash-4.4$ jobs -l
[1]+ 24807 Running                 sleep 1000 &
bash-4.4$ cd /
bash-4.4$ jobs -l
[1]+ 24807 Running                 sleep 1000 &  (wd: /tmp)

ksh93不这样做

$ sleep 1000 &
[1]     7164
$ jobs -l
[1] + 7164       Running                 sleep 1000 &
$ cd /
$ jobs -l
[1] + 7164       Running                 sleep 1000 &
$ 

我不相信有任何可移植的方法来查找进程的 cwd。 fstatpwdx类似的可能会有所帮助。您可能需要root权限才能查看不属于您的进程。

在 Linux 上,可以通过查看符号链接来使用与特定路径匹配的进程/proc/.../cwd

例如,查找/tmp路径中的进程:

% sudo ls -l /proc/*/cwd | grep /tmp
lrwxrwxrwx. 1 sweh     sweh     0 Jul 28 09:38 /proc/23435/cwd -> /news/tmp
lrwxrwxrwx. 1 sweh     sweh     0 Jul 28 09:39 /proc/7124/cwd -> /news/tmp

请记住,由于符号链接,这可能与进程的目录内部表示不匹配:

$ cd /usr/tmp
$ pwd
/usr/tmp
$ ls -l /proc/self/cwd
lrwxrwxrwx. 1 sweh sweh 0 Jul 28 09:41 /proc/self/cwd -> /var/tmp/
$ ls -l /usr/tmp
lrwxrwxrwx 1 root root 10 May 13 09:39 /usr/tmp -> ../var/tmp/
$ 

外壳认为我在里面,/usr/tmp但实际上它在里面/var/tmp

编辑添加:

此问题有一个特殊情况,其中问题可能是“哪些进程正在使用安装点”。这不是报告cwd任何可能打开的文件。

因此,例如:

$ sudo fuser -u -c /brick
/brick:               3552(root)
$ ps -p 3552
  PID TTY          TIME CMD
 3552 ?        00:04:51 glusterfsd
$

我们知道该glusterfsd进程是唯一使用/brick文件系统的进程

答案2

没有一种可移植的方法来执行此操作ps,但您可以使用 for 循环来ps打印所有进程,然后将其通过管道传输到另一个命令来打印其当前工作目录。

让我们从pwdx专门打印进程的当前工作目录开始。

以 root 身份运行:

for i in $(ps aux | awk '{print $2}'); do pwdx $i; done

ps aux | awk '{print $2}'打印每个进程的 pid。

pwdx $i将 pid 的 i 变量传递给pwdx

您可以pwdx在 pid 本身上使用,但 for 循环将它们一起执行。

您也可以使用,但根据您的系统,lsof您可能需要先安装该软件包。lsof以 root 身份运行:

for i in $(ps aux | awk '{print $2}'); do lsof -p $i | grep cwd; done

ps aux | awk '{print $2}'打印每个进程的 PID。

lsof -p $i将 i 变量传递给lsof

grep cwdcwd打印包含当前工作目录的行。

关于pgrep命令,您可以使用以下形式:

pgrep <process-name>

为了也找到进程的 pid,但您仍然必须将其传递给lsofpwdx来查找当前工作目录。

第一个for loop适用于 Fedora 28、Centos 7.5、RHEL 7.5 和 Debian 9,但不适用于 FreeBSD 11。

第二个for loop适用于 Fedora 28、Centos 7.5、RHEL 7.5 和 Debian 9。它也适用于 FreeBSD 11.1,尽管在我的例子中,它打印出有关lsofFreeBSD 11 版本的警告消息,而我的是 FreeBSD 11.1

答案3

许多操作系统中的其他进程都知道进程的工作目录。在 BSD 和 Linux 上,可以分别使用sysctl()和从内核中查询它们procfs。然而,Linux 都没有ps但是, procps 中的ps命令和BSD 中的命令都不会获取并报告此信息。

要获取 BSD 上进程的当前目录,命令是fstat,它报告文件系统和 i 节点号。

% fstat -p $$|awk '{ if ("wd" == $4 || 1 == NR) 打印; }'
用户命令 PID FD 安装 INUM 模式 SZ|DV R/W
JdeBP zsh 71512 wd /usr/home/JdeBP 4 drwxr-xr-x 127 r
%

请注意,当然,工作目录可以通过多个名称访问,并且这些名称可能会随着内容的重命名和链接的创建/销毁而变化。其中稳定的部分是文件对象、vnode,而不是用于到达它的目录条目。

因此,在 中报告一个名称的 Linux 机制并不一定可靠。/proc/pid/cwd

最后:请注意当前的进程的目录不一定是进程生成时的工作目录,这是所有作业控制 shell实际上知道。

进一步阅读

相关内容