我试图理解 Ethan 的 shell 脚本这个帖子,用于发现操作系统上的最大和最小进程 ID。
pid=0
for i in {1..100000}; do
: &
if [ $! -lt $pid ]; then
echo "Min pid: $!"
echo "Max pid: $pid"
break
fi
pid=$!
done
我知道它$
替代了 shell 参数,并且!
是范围存储“最近执行的后台(异步)命令”的 PID。进一步地,&
是一个控制操作员当在命令末尾使用时:在后台进程中调用前面的任何内容。因此,打开一个新的 shell 实例并运行: &
,然后运行$!
,我们得到:
% : &
[1] <PID>
[1] + done :
% $!
<PID>
每次调用的位置都<PID>
不同。有什么if [ $! -lt $pid ]; then
作用?为什么脚本成功地从最小 PID 变化到最大 PID(即一致输出100
和99998
)?决赛是pid=$!
为了什么?如果有的话,计数器会i
出现在脚本的什么位置(除了重复 100,000 次)?
答案1
i
仅用于运行足够的进程来尝试操作系统范围内的每个可能的 PID(某些操作系统允许更大的 PID 范围)。请注意,这将从该范围内的任意点开始,具体取决于自启动以来运行的进程数量。
: &
运行一个不执行任何操作的命令,但它会被分配一个唯一的 PID(无论如何,在它启动时是唯一的)。
该脚本假定操作系统按递增的数字顺序分配 PID,并跳过正在使用的任何 PID。这就是许多类 Unix 操作系统的工作原理,包括 Linux(默认情况下)。该脚本还假设最大进程 ID 小于 100000,这在 Linux 上是正确的(15 位 PID),但在现代 Linux 系统上则不然。
只要 PID 大于我们见过的最高值,我们就会存储新的高值并继续前进。
当操作系统用完 PID 时,它将循环并从高于保留范围且当前未使用的最低 PID 开始。
第一次发生这种情况时,我们报告刚刚获得的低 PID,以及结束前的最高 PID,然后就完成了。
Linux 将所有作业控制消息(数千条)发送到终端。我通过将最后一行更改为以下内容来重定向整个标准输出输出:
done > /dev/null
并将转到 stderr 的两个 echo 替换为:
printf 1>&2 'Pid range: min %d, max %d\n' $! $pid