前言

本文主要记录📝平时学到关于Shell的一些知识,方便复习.


知识

如何在脚本中获取进程ID(PID)?

在运行Shell脚本时,主shell并不会去运行,而是创建一个子Shell进程去运行我们的Shell脚本.

子shell将shell脚本中的命令作为批处理运行(因此称为“批处理进程”)

img

在某些情况下,我们需要知道运行中子shell的进程ID(PID).

那么PID可以用来做什么呢?

  • PID信息可以用来在/tmp下创建一个唯一的临时文件
  • 有时脚本需要检测所有运行的进程,PID可以从进程列表中排除自身的子shell
  • 等等

在bash中,子shell进程的PID存储在一个特殊的变量‘$$’中。这个变量只读,你不可以在脚本中修改它.

1
echo "PID of this script: $$"

image-20220520143403683

除了$$$$, bash shell还会导出其他的只读变量。比如,PPID存储子shell父进程的ID(也就是主shell)。UID存储了执行这个脚本的当前用户ID。比如:

1
2
3
4
5
#!/bin/bash

echo "PID of this script: $$"
echo "PPID of this script: $PPID"
echo "UID of this script: $UID"

image-20220520143528058

上面输出中,PID每次执行都会变化。这个因为每次运行都会创建一个新的shell.

而对于PPID来说,只要主shell没有变更,那么PPID也不会变更.

那么PID和PPID有什么区别吗,它们分别是什么?

讲这个之前,先来浅说一下程序和进程分别是什么.

  • 程序:程序是静止的,程序就是存储在磁盘上的可执行文件.

  • 进程:进程是动态的,进程是一个加载到内存并运行的程序.

终端输入top你能看到当前加载到内存中的所有进程的进程ID,无论其状态如何(睡眠、僵尸等),守护进程(系统进程)和用户进程(您自动或手动启动的进程)都有自己的进程ID.

说到这,应该就能理解为什么PPID不会改变,而PID会改变了吧.

接下来说说PID和PPID

PID(process ID):

PID是程序被操作系统加载到内存成为进程后动态分配的资源。

每次程序执行的时候,操作系统都会重新加载,故PID在每次加载的时候都是不同的。

PPID(parent process ID):PPID是程序的父进程号。

要点:

  • PID 是唯一的,一个 PID 只标识一个进程。

  • PID 并不总是按数字顺序分配.

  • 一个进程创建的另一个新进程称为子进程。相反地,创建子进程的进程称为父进程。

  • 对于一个普通的用户进程,它的父进程就是执行它的哪个Shell,对于Linux而言,Shell默认为bash.

  • init是系统上所有进程的父进程.

  • init进程(进程号PID为1)是linux内核(内核本身的PID为0)启动后第一个执行的进程。

  • init进程引导系统,启动守护进程并且运行必要的程序。

C语言获取PID和PPID的函数:

  • 获取进程的PID:pid_t getpid(void);

  • 获取进程的PPID:pid_t getppid(void);

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *args[])
{
// 获取当前进程的PID
pid_t pid = getpid();
printf("pid = %d\n", pid);

// 获取当前进程的PPID
pid_t ppid = getppid();
printf("ppid = %d\n", ppid);

return 0;
}

关于更多对bash的了解或学习.

可以参考man页man bash或者查看Bash4.0参考文档.pdf

未完待续!…