LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 155|回复: 0

checkpid、__pids_var_run和__pids_pidof函数

[复制链接]
发表于 2023-12-18 15:28:12 | 显示全部楼层 |阅读模式

checkpid、__pids_var_run和__pids_pidof函数
pid文件的路径可能为/var/run/$base.pid文件(​$base表示进程名的basename),也可能是自定义的路径,例如mysql的pid可以自定义为/mysql/data/mysql01.pid。但无论哪种情况,functions中的__pids_var_run函数都可以处理。

pid文件中可能有多行,表示多实例。

每个进程都必有一个pid,但并不一定都记录在pid文件中,例如线程的pid。但无论如何,在/proc/目录下,一定会有pid号命名的目录,只要有对应pid号的目录,就表示该进程已经在运行。函数checkpid专门检测给定的pid值在/proc下是否有对应的目录存在。

为了获取进程名的pid值,此处函数__pids_pidof使用的是pidof命令。该命令专门设计用来在脚本中取给定进程的pid。它的”-o”选项用于忽略某些进程号,在脚本中应用时常被忽略的是调用pidof的shell的PID,当前shell的PID以及父shell的pid。总之,该函数的目的就是为了获取合理无误的进程pid。

以下是函数checkpid、__pids_var_run和__pids_pidof的定义语句。

# Check if any of $pid (could be plural) are running
checkpid() {
    local i

    for i in $* ; do          # 检测/proc目录下是否存在给定的进程目录
        [ -d "/proc/$i" ] && return 0
    done
    return 1
}

# __proc_pids {program} [pidfile]
# Set $pid to pids from /var/run* for {program}.  $pid should be declared
# local in the caller.
# Returns LSB exit code for the 'status' action.
__pids_var_run() {                # 通过检测pid判断程序是否已在运行
    local base=${1##*/}           # 获取进程名的basename
    local pid_file=${2:-/var/run/$base.pid}     # 定义pid文件路径

    pid=
    if [ -f "$pid_file" ] ; then        # 给定的pid文件是否存在
            local line p

        [ ! -r "$pid_file" ] && return 4   # "user had insufficient privilege"
        while : ; do                       # 将pid文件中的pid值(可能有多行)赋值给pid变量
            read line
            [ -z "$line" ] && break
            for p in $line ; do
                [ -z "${p//[0-9]/}" ] && [ -d "/proc/$p" ] && pid="$pid $p"
            done
        done < "$pid_file"

            if [ -n "$pid" ]; then  # pid存在,则返回0。否则表示pid文件存在,但/proc下没有对应命令
                    return 0        # 即进程已死,但pid文件却存在,返回状态码1。
            fi
        return 1 # "Program is dead and /var/run pid file exists"
    fi
    return 3 # "Program is not running"    # pid文件不存在时,表示进程未运行,返回状态码3
}

# Output PIDs of matching processes, found using pidof
__pids_pidof() {             # 下面的pidof命令的意义见稍后解释
    pidof -c -m -o $$ -o $PPID -o %PPID -x "$1" || \   # 忽略当前shell的PID,父shell的pid和
                                                       # 调用pidof程序的shell的pid
        pidof -c -m -o $$ -o $PPID -o %PPID -x "${1##*/}"    # 总之就是找出合理的pid
}
从__pidsvar_run函数的定义语句中可以了解到,只有当pid文件存在,且/proc下有pid对应的目录时,才表示进程在运行(当然,线程没有pid文件)。__pids_var_run函数调用方法:

__pids_var_run program [pidfile]
如果不给定pidfile,则默认为/var/run/$base.pid文件。函数的执行结果为4种状态码:

0:program正在运行。
1:program进程已死。pid文件存在,但/proc目录下没有对应的文件。
3:pid文件不存在。
4:pid文件的权限错误,不可读。
除了返回状态码,__pids_var_run函数还会保存变量pid的结果,以供其他程序引用。

__pids_pidof中使用了pidof命令,其中使用了几个”-o”选项,它用于忽略指定的pid。但看上去$$ $PPID %PPID不是很好理解。-o $$是忽略的是shell进程,大多数时候它会继承父shell的pid,但在脚本中时它代表的是脚本所在shell的pid。-o $PPID忽略的是父shell。-o %PPID忽略的是调用pidof命令的shell。不是很好理解,可以参考下面的测试语句。

测试脚本:

#!/bin/bash

echo 'pidof bash: '`pidof bash`
echo 'script shell pid: '`echo $$`
echo 'script parent shell pid: '`echo $PPID`
echo 'pidof -o $$ bash: '`pidof -o $$ bash`
echo 'pidof -o $PPID bash: '`pidof -o $PPID bash`
echo 'pidof -o %PPID bash: '`pidof -o %PPID bash`
echo 'pidof -o $$ -o $PPID -o %PPID bash: '`pidof -o $$ -o $PPID -o %PPID bash`
测试语句:

[root@xuexi ~]# pidof bash
3306 2436 2302
[root@xuexi ~]# (echo 'parent shell: '$$;echo "current bash pid: `pidof bash`";./test.sh)|cat -n
1  parent shell: 2302
2  current bash pid: 3745 3306 2436 2302
3  pidof bash: 3748 3745 3306 2436 2302
4  script shell pid: 3748
5  script parent shell pid: 3745
6  pidof -o $$ bash: 3745 3306 2436 2302
7  pidof -o $PPID bash: 3748 3306 2436 2302
8  pidof -o %PPID bash: 3745 3306 2436 2302
9  pidof -o $$ -o $PPID -o %PPID bash: 3306 2436 2302
第一个pidof命令:说明当前已有3个bash,pid为:3306、2436和2302。
第二个命令:

行1说明括号的父shell为2302。
行5说明脚本的父shell为3745。即括号的父shell为当前bash环境,脚本的父shell为括号所在shell。
行2减第一个命令的结果说明括号所在子shell的pid为3745。
行3减行2说明shell脚本所在子shell的pid为3748。
-o $$忽略的是当前shell,即脚本所在shell的pid,因为在shell脚本中时,​$$不继承父shell的pid。
-o $PPID忽略的是pidof所在父shell,即括号所在shell。
-o %PPID忽略的是调用调用pidof程序所在的shell,即脚本所在shell。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表