概括
以mirage
一个以 shebang 开头的 python 程序为例:
#!/usr/bin/python
...
看着/proc/<pid>/comm
或使用pgrep
,它看起来像......
...当我通过 shebang 调用它时,进程名称是“mirage”:
/usr/bin/mirage &
...但是当我显式调用 python 时是“python”:
/usr/bin/python /usr/bin/mirage &
- 我知道进程可以更改自己的名称,但为什么两种情况下的名称不同?
- 是否有一种通用方法可以了解流程最初是如何启动的(仅使用
/proc
或grep
信息)?
详情-舍邦
/home/martin> /usr/bin/mirage &
[1] 22638
/proc/<pid>/comm说这是“海市蜃楼”
/home/martin> cat /proc/22638/comm
mirage
程序包发现它是“mirage”,但不是“python”
/home/martin> pgrep -al mirage && echo "found" || echo "not found"
22638 /usr/bin/python /usr/bin/mirage
found
/home/martin> pgrep -al python && echo "found" || echo "not found"
not found
详细信息 - python
/home/martin> /usr/bin/python /usr/bin/mirage &
[1] 21348
/proc/<pid>/comm说它是“蟒蛇”
/home/martin> cat /proc/21348/comm
python
程序包发现它是“python”,但不是“mirage”
/home/martin> pgrep -al mirage && echo "found" || echo "not found"
not found
/home/martin> pgrep -al python && echo "found" || echo "not found"
21348 /usr/bin/python /usr/bin/mirage
found
答案1
进程名称源自argv[0]
调用execv()
。
这解释了您观察到的行为。
事实上,在 shebang 情况下,内核重新排列事物的调用方式不会影响向量argv
。
答案2
我知道进程可以更改自己的名称,但为什么两种情况下的名称不同?
因为涉及到的程序有不是改变自己的名字。它们被赋予 Linux 默认行为分配的名称。 (其他操作系统的行为有所不同,但这是一个 Linux 问题,因为它讨论的是/proc/*/comm
文件。)
在 Linux 上,程序名称comm
取自任何程序映像文件名称传递给execve()
was。请注意,这不是参数向量或环境向量,并且该名称取自 Linux 上的参数向量的说法是错误的。
shell 实际传递的程序映像文件名是/usr/bin/python
和/usr/bin/mirage
,因此python
和mirage
是/proc/self/comm
初始化的内容。 (comm
是程序图像文件名的基本名称,已截断/填充。)
参数向量初始化进程在其中的内容/proc/self/cmdline
,环境向量初始化其在中的内容/proc/self/environ
。因此,有了这些 和/proc/self/comm
,并假设程序在运行时不会改变它们,您就知道传递给的所有三个信息execve()
,因此确切地知道“进程最初是如何启动的”(尽管严格来说,这是如何该程序已推出,如过程与 ) 一起启动fork()
。
下面是这三个部分的实际操作示例,使用nosh 工具集中的clearenv
、setenv
和exec
来设置一个小环境和力argv[0]
以进行说明:
%clearenv setenv 1THIS '是环境字符串' setenv 2COMPRISING '所有环境。 \ > exec -a '这是 argv[0]。' /bin/sleep 100 & [1]15564 % for i in /proc/$\!/{comm,cmdline,environ} ;执行 printf "%s:" $i ;猫 -v $i ; printf "\n" ;完毕 /proc/15564/通讯:3 /proc/15564/cmdline:这是argv[0].^@100^@ /proc/15564/environ:1THIS=环境字符串^@2COMPRISING=所有环境。^@ %
事实上,这些正是 nosh 工具集的exec
命令传递给execve()
运行的命令/bin/sleep
。 (这3
是因为exec
使用了 C 库的fexecve()
函数,该函数在内部使用 形式的程序映像文件名/proc/self/fd/3
。)
程序映像文件恰好是一个带有命名解释器和#!
幻数的脚本,导致该解释器替换程序映像文件并移动参数向量,没有改变什么进入comm
.它保留最初赋予的任何程序映像文件名execve()
。是的,Linux 在这里是不一致的,因为它做将这种情况下的内容更改cmdline
为有效的最终参数字符串。
进一步阅读
- https://unix.stackexchange.com/a/432681/5132
- https://unix.stackexchange.com/a/438007/5132
- https://unix.stackexchange.com/a/257568/5132
- https://unix.stackexchange.com/a/392600/5132
- 乔纳森·德博因·波拉德 (2018)。 ”
clearenv
”。 手动的。诺什工具集。软件。 - 乔纳森·德博因·波拉德 (2018)。 ”
setenv
”。 手动的。诺什工具集。软件。 - 乔纳森·德博因·波拉德 (2018)。 ”
exec
”。 手动的。诺什工具集。软件。