这个脚本
$ cat csub.sh
#!/bin/bash
while true;
do
sleep 5
AVAR=$(date; sleep 2)
done
启动时,使进程出现在 ps 输出中:
ps -eLf|egrep '[c]sub.sh|PID'
UID PID PPID LWP C NLWP STIME TTY TIME CMD
jimmy 31364 23445 31364 0 1 00:33 pts/7 00:00:00 /bin/bash ./csub.sh
这是完全可以预测的,而且事实上$(date; sleep 2)
会产生另一个进程
令人惊讶的是,生成的进程有完全相同的显示命令
UID PID PPID LWP C NLWP STIME TTY TIME CMD
jimmy 31364 23445 31364 0 1 00:33 pts/7 00:00:00 /bin/bash ./csub.sh
jimmy 31433 31364 31433 0 1 00:33 pts/7 00:00:00 /bin/bash ./csub.sh
我添加了 sleep 以便能够将进程捕获到 ps 输出中,否则机会就会少得多,因为它太短了。正如您所看到的,生成的进程 31433 有 31364 作为其父进程。我希望生成的进程有一些不同的 CMD 提及它处理的内容,例如日期或睡眠命令。对于存在多个命令替换的情况,当我看到生成的进程出现时,如何区分它们?
答案1
在手册页的第 2 部分中fork()
:
fork()
通过复制调用进程来创建一个新进程。新进程(称为子进程)与调用进程(称为父进程)完全相同,但以下几点除外:
- 子进程有自己唯一的进程 ID,并且该 PID 与任何现有进程组 ( ) 的 ID 都不匹配
setpgid(2)
。- 子进程的父进程 ID 与父进程 ID 相同。
- 子进程不会继承其父进程的内存锁 (
mlock(2)
,mlockall(2)
)。- 子进程中的进程资源利用率 (
getrusage(2)
) 和 CPU 时间计数器 (times(2)
) 重置为零。- 子级的待处理信号集最初为空 (
sigpending(2)
)。- 子级不会从其父级 (
semop(2)
) 继承信号量调整。- 子级不会从其父级 (
fcntl(2)
) 继承记录锁。- 子级不会从其父级 (
setitimer(2)
,alarm(2)
,timer_create(2)
) 继承计时器。- 子级不会从其父级继承未完成的异步 I/O 操作(
aio_read(3)
、aio_write(3)
),也不会从其父级继承任何异步 I/O 上下文(请参阅io_setup(2)
)。
进程的调用命令行不在此列表中,因此它将与其父进程相同。您可以区分子进程和父进程,因为子进程的 PPID(父进程 PID)将是原始进程的 PID。