是否有特殊设备导致读取永远阻塞?

是否有特殊设备导致读取永远阻塞?

我正在寻找一种/dev/null导致read永远阻塞的变体,而不是立即返回 EOF。这样的设备存在吗?

我可能可以创建一个命名管道(通过mkfifo)来实现所需的效果,但我不想在脚本末尾处理取消链接 FIFO 的问题。

对于上下文,我想等待 RPC 服务器退出。为了避免轮询,我通过 netcat 打开连接:

netcat localhost 12345

当服务器关闭时,连接将自动关闭。不幸的是,当通过 SSH 运行命令时,stdin 设置为/dev/null,因此 netcat 在发送 EOF 后立即退出,而不是等待连接关闭。netcat -d(不要等待标准输入)有错误吗?在 macOS 上并且很热,这意味着该解决方案实际上比以合理的时间间隔进行轮询更糟糕。

我有一个解决这个问题的方法——将标准输入连接到管道——但出于纯粹的好奇心,我对这个问题特别感兴趣。

答案1

不幸的是,当通过 SSH 运行命令时,stdin被设置为/dev/null,因此netcat在发送后立即退出EOF,而不是等待连接关闭。

bash版本 4 中,我们可以创建一个协进程read,通过管道连接到父进程,并从其始终打开但为空的进程中读取数据stdout。此方法不需要清理。

例子:

coproc read # Never writes anything into its stdout.
netcat localhost 12345 <&${COPROC[0]} # Read from co-process' stdout.

另一种方法是stdinstdoutlong进行管道传输sleep

sleep 365d | netcat localhost 12345

答案2

您可以使用cryptsetup(或者,我猜,dmsetup也可以)创建一个。

# truncate -s 8M luksblock.img
# cryptsetup luksFormat luksblock.img
# cryptsetup luksOpen luksblock.img luksblock
# cryptsetup luksSuspend luksblock
# cat /dev/mapper/luksblock
( ... no output because it's blocked / suspended ... )

它看起来像什么dmsetup

# dmsetup info luksblock
Name:              luksblock
State:             SUSPENDED
Read Ahead:        256
Tables present:    LIVE
Open count:        0
Event number:      0
Major, minor:      253, 71
Number of targets: 1
UUID: CRYPT-LUKS1-87bc6d9fd7fa419bbf15425c062d0916-luksblock

您可以使用dmsetup暂停设备:

dmsetup suspend luksblock

因此,应该可以创建一个不需要文件支持的挂起设备映射luksblock.img,但我将把最后一点留给您。 :-P


当然,这种方法有一个重大缺点。该设备将在 中的所有其他块设备中列出/proc/partitions,并且监视或检测设备的所有内容(例如寻找新物理卷的 LVM)也将尝试读取并卡在该块上。这将阻止设备被检测到(因为执行此操作的进程被卡住),并且计算机也可能不再重新启动(因为处理关闭过程的进程被卡住)。

相关内容