Shell 脚本中的 `:&`

Shell 脚本中的 `:&`

我试图理解 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(即一致输出10099998)?决赛是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

相关内容