gpt4 book ai didi

c - 测试我的程序是否从 bash/ksh/csh 命令行执行

转载 作者:IT王子 更新时间:2023-10-29 00:41:42 26 4
gpt4 key购买 nike

我想知道我的程序是从命令行执行的,还是通过 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());
}


$ ./pp
pid=3164 pgrp=3164
$ ./pp &
[1] 3165
$ pid=3165 pgrp=3165

在管道中,最左边的命令是进程组的领导者。 (这没有记录在案,但 bash、ksh93 和 tcsh 都是这样做的)。

$ ls|./pp
pid=3179 pgrp=3178
$ ./pp|cat
pid=3180 pgrp=3180

system() 调用的程序将具有与其父级相同的 pgrp:

pps.c

#include <stdlib.h>

main()
{
system("./pp");
}


$ ./pps
pid=4610 pgrp=4608

在shell脚本中,shell是进程组的领导者,它调用的任何命令都会继承pgrp:

pp.sh

#!/bin/sh
./pp


$ ./pp.sh
pid=4501 pgrp=4500

但如果 shell 脚本 exec 是一个程序,则 pid 不会改变,并且被执行的程序将成为进程组组长,因此您可能不想那样做。

ppe.sh

#!/bin/sh
exec ./pp


$ ./ppe.sh
pid=4504 pgrp=4504

在极少数情况下,用户会关闭作业控制,每个命令都将具有与 shell 相同的 pgrp:

$ set +m
$ ./pp
pid=4521 pgrp=2990
$ ./pp
pid=4522 pgrp=2990

关于c - 测试我的程序是否从 bash/ksh/csh 命令行执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24332038/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com