确定进程是直接从终端窗口启动还是以编程方式作为子进程启动

确定进程是直接从终端窗口启动还是以编程方式作为子进程启动

如果用户从终端运行一个进程,是否可以知道?与从程序启动进程相比,该程序是从终端启动。

用例是如果它由终端运行,它将如下所示:

suman:
suman:
suman:

但如果它由另一个程序 x 运行,如果 x 在 stdout/stderr 前面添加一些内容,则它可能看起来像这样:

x: suman:
x: suman:

但我想检测到这一点,所以它看起来像:

x:
x:    
x:

答案1

您可以查看相关进程的父进程 ID (PPID),然后使用 PPID 来确定它是从 shell 还是其他程序运行。

例如,如果我想查看该sleep进程正在运行的内容,我可以查找它的 PPID。

$ ps -ef | grep "sleep"
user       2470  1996  0 06:30 pts/1    00:00:00 sleep 60

PID 1996 是进程的 PPID sleep。现在让我们grep开始吧。

$ ps -ef | grep 1996
user       1996  1995  0 05:57 pts/1    00:00:00 bash

PID 1996 是一个bashshell,这很好地表明了该sleep进程可能从终端运行。要更进一步,您可以grep获取进程的 PPID bash

$ ps -ef | grep 1995
user       1995   448  0 05:57 tty1     00:00:00 /usr/bin/urxvt

进程的 PPIDbashurxvt,一个虚拟终端。所以该sleep命令是从终端运行的。

答案2

当您获取使用 .或之前的来源,命令附注不会列出源脚本名称。因此,一种方法是执行 grep 来检查 ps 输出中是否包含源脚本名称,表明它不是源脚本。

示例:假设文件“myscript”具有以下命令:

cd /run/user/1000  #it will only affect terminal pwd if is sourced!

如果直接运行:

$ myscript  # ps will contain 'myscript' in the list.
# The cd command will not change the terminal current directory (pwd)

否则,如果您在前面使用“source”或点 (.):

$ . myscript       # ps will not list "myscript" as it was sourced
$ source myscript  # source works the same as .
# Your terminal pwd will change to /run/user/1000

更改 'myscript' 使其生效:

ck=`ps | grep -o -m 3 -E 'myscript'`

cd /run/user/1000

if [ -n "$ck" ]; then # -n means "not empty"
  printf "\E[07;91mYou must source the script, run . myscript\E[0m\n"
  exit
fi

# or negative logic ... 

if [ -z "$ck" ]; then  # -z means null, empty
  echo "You are runnig the sourced script, now run pwd to check it"
fi

相关内容