我正在寻找一种/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.
另一种方法是stdin
从stdout
long进行管道传输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)也将尝试读取并卡在该块上。这将阻止设备被检测到(因为执行此操作的进程被卡住),并且计算机也可能不再重新启动(因为处理关闭过程的进程被卡住)。