我想知道我的程序是从命令行执行,还是通过system()调用执行,还是从脚本执行.
我最初想过获取父id(getppid()),并查找/proc/#pppid目录检查文件的exe链接或内容cmdline.如果它是/ bin/bash,或/ bin/csh,或/ bin/sh,我会知道它是从命令行运行的.
问题是它不是真的,因为一个独立的脚本也会告诉我/bin/bash.即使它工作,它可能是非常具体的Linux版本方法,并可能在未来停止工作.
有没有更好的方法呢?
感谢您提出任何建议或指出某些方向.
自 1980 年以来编写的大多数 shell 都支持作业控制,这是通过为命令管道中的每个进程分配进程组来实现的。进程组由setpgrp()设置,它将进程的 pgrp 设置为其 pid。
pgrp 是跨分支继承的。
因此,如果您的 shell 是一个相对现代的 shell,则由交互式 shell 启动的程序将具有getpid() == getpgrp(),并且该进程派生的任何其他进程(例如,如果它是 shell 脚本或调用system())将具有getpid() != getpgrp()。
这是一个测试程序,及其在 bash 下的行为(它在 ksh93 和 tcsh 下的行为也相同):
pp.c
#include <unistd.h>
#include <stdio.h>
main()
{
printf("pid=%d pgrp=%d\n", (int)getpid(), (int)getpgrp());
}
Run Code Online (Sandbox Code Playgroud)
$ ./pp
pid=3164 pgrp=3164
$ ./pp &
[1] 3165
$ pid=3165 pgrp=3165
Run Code Online (Sandbox Code Playgroud)
在管道中,最左边的命令是进程组领导者。(这没有记录,但 bash、ksh93 和 tcsh 都是这样做的)。
$ ls|./pp
pid=3179 pgrp=3178
$ ./pp|cat
pid=3180 pgrp=3180
Run Code Online (Sandbox Code Playgroud)
调用 with 的程序system()将与其父程序具有相同的 pgrp:
pps.c
#include <stdlib.h>
main()
{
system("./pp");
}
Run Code Online (Sandbox Code Playgroud)
$ ./pps
pid=4610 pgrp=4608
Run Code Online (Sandbox Code Playgroud)
在shell脚本中,shell是进程组领导者,它调用的任何命令都会继承pgrp:
pp.sh
#!/bin/sh
./pp
Run Code Online (Sandbox Code Playgroud)
$ ./pp.sh
pid=4501 pgrp=4500
Run Code Online (Sandbox Code Playgroud)
但是如果shell脚本exec是一个程序,pid不会改变,并且执行的程序将是进程组的领导者,所以你可能不想这样做。
ppe.sh
#!/bin/sh
exec ./pp
Run Code Online (Sandbox Code Playgroud)
$ ./ppe.sh
pid=4504 pgrp=4504
Run Code Online (Sandbox Code Playgroud)
在不太可能发生的情况下,用户关闭作业控制,每个命令都将具有与 shell 相同的 pgrp:
$ set +m
$ ./pp
pid=4521 pgrp=2990
$ ./pp
pid=4522 pgrp=2990
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
333 次 |
| 最近记录: |