- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我想知道我的程序是从命令行执行的,还是通过 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/
我想知道为什么下面的小脚本现在可以工作。 我在/data 目录下创建了 dfFile 但脚本没有打印 if 语句中的表达式。 #!/bin/ksh DATAFILE="/data/dfFile" ec
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我正在编写一个简单的 ksh 脚本。我必须检查字符串是否为空。怎么做呢?这就是我所拥有的: findRes=`find . -name believe | xargs grep -q "ser"` i
首先介绍一点背景知识:我们有 9 个 JVM 服务器,它们输出日志文件,我不断地解析这些日志文件以查找何时发生错误。日志每 5-10 分钟滚动一次,但文件名不会更改。我使用 SupperPutty 打
当脚本由 ksh 提供时,它如何确定它的路径? IE。 $ ksh ". foo.sh" 我已经在 stackoverflow 和其他地方发布的 BASH 中看到了非常好的方法,但还没有找到 ksh
我在某处读到 ksh 的数组支持 += 来追加新元素,但我试过了,它不起作用: [ksh] # arr=(a b c d) [ksh] # arr+=e [ksh] # echo ${arr[*]}
在我的 ksh 脚本中,我有参数 VERSION=3.9.2X。 $VERSION 始终以 3.9.2 开头,X 可以是任何整数或 float 。 以下不规则 ksh 语法适用于任何 X 整数,但不适
我参与了将包含数百个 ksh 脚本的系统从 AIX、Solaris 和 HPUX 移植到 Linux 的过程。我发现 ksh 在两个系统上的行为方式存在以下差异: #!/bin/ksh flag=fa
我正在编写一个 Expect 脚本并且在处理 shell 提示时遇到了麻烦(在 Linux 上)。我的 Expect 脚本生成 rlogin并且远程系统正在使用 ksh .远程系统上的提示包含当前目录
我讨厌 eval... 我被这个 ksh 困住了,它必须是这样的。 我需要这个函数,它将接收一个变量名和一个值。将对该变量的内容和值做一些事情,然后必须更新接收到的变量。排序: REPORT="a t
我希望我的 ksh 脚本具有不同的行为,具体取决于是否有通过 stdin 传入的内容: (1) cat file.txt | ./script.ksh (then do "cat ./tmp
set -o vi-tabcomplete正在打开选项卡自动完成 和 set -o emacs正在打开历史记录(上一个命令向上,下一个命令向下) 但是,如果我同时在 ~/.kshrc 中设置,它只会打
#!/bin/ksh ######################### for i in {1..30} ;do echo $i done 输出是: {1..30} 我的代码有什么问题
我编写了一个示例 KornShell 函数来拆分字符串,将其放入数组中,然后打印出值。 代码如下 #!/usr/bin/ksh splitString() { string="abc@hotm
我需要检查变量是否具有以指定子字符串开头的字符串值。 在 Python 中,它会是这样的: foo = 'abcdef' if foo.startswith('abc'): print 'Su
我正在尝试在 ksh 中构建一种属性集。 我认为最简单的方法是使用数组,但语法太让我难受了。 我想要的是 在配置文件中构建具有名称和属性的任意大小的数组。 迭代该列表中的每个项目并获取该属性。 我理论
我正在尝试在 ksh 中构建一种属性集。 我认为最简单的方法是使用数组,但语法太让我难受了。 我想要的是 在配置文件中构建具有名称和属性的任意大小的数组。 迭代该列表中的每个项目并获取该属性。 我理论
我需要知道执行赋值的命令的退出状态。 export VALUE=`My_Get_Value 10` 我需要知道 My_Get_Value 脚本的退出状态。 在$?中,我拥有分配本身的状态。 我在 KS
我使用内置的“getopts”ksh 来处理命令行选项,我正在寻找一种干净/标准的方法来“取消设置”命令行上的选项。我不知道这是关于 getopts 的技术问题还是更多的风格/标准问题。无论如何,我知
在 ksh 中,如下所示 iname=FA USER_FA=xyz USER_CS=test TDUSER=USER_$iname ${!TDUSER} ${!TDUSER} 未按预期工作。为什么?
我是一名优秀的程序员,十分优秀!