Bash 中的简单或简单的检查时间到使用时间场景是什么?

Bash 中的简单或简单的检查时间到使用时间场景是什么?

通常,当用 Bash 解释软件开发概念时,我比用 JavaScript 解释得更好。

关于检查时间到使用时间(TOCTOU),它在维基百科当前的开头段落:

在软件开发中,检查时间到使用时间(TOCTOU、TOCTTOU 或 TOC/TOU)是一类由竞争条件引起的软件错误,涉及系统部分状态的检查(例如安全凭证)以及该检查结果的使用。

Bash 中的简单或简单的检查时间到使用时间场景是什么?

答案1

我在本网站上看到的该类型最常见的竞争条件与进程 ID (PID) 的处理以及基于这些的信号发送有关。

有人可能会使用ps+grep来获取某个命名进程的 PID,然后kill向其发出信号。在获取 PID 和发送信号之间,PID 可能已经消失。使用pkill可以最大限度地减少此错误发生的窗口。

在其他情况下,保留 PID 并期望它在较长时间内始终引用同一进程(例如,在“PID 文件”中)可能会导致信号发送到错误的进程。这是因为所有 Unix 系统都重用 PID。

另一个常见问题是文件锁定,即使用文件系统为多进程同步和临界区提供锁定机制。例如,可以测试某个“锁定文件”是否存在,如果不存在,则创建它并从而“获取锁定”。在检查文件存在和创建锁定文件之间,其他进程也有机会意识到锁定文件不存在:

while [ -e "$lockfile" ]; do
    sleep 10
done
touch "$lockfile"
echo 'got lock'  # or did I?

# do work

rm -f "$lockfile"

解决方案在情况是使用专用的文件锁定工具,例如flock,或使用锁目录,因为mkdir是原子的:

while ! mkdir "$lockdir" 2>/dev/null; do
    sleep 10
done
echo 'got lock'

# do work

rmdir "$lockdir"

这在 NFS 等网络文件系统上仍然无法可靠地工作,因为这些系统不提供目录创建的原子操作。

无疑还有很多其他的例子。

相关内容