如何防止用户在 read -n 命令期间将文件作为输入拖入

How to prevent user from dragging in a file as input during read -n command

我有一个 bash 脚本,它要求用户从某些菜单屏幕向 select 进行单键输入。我正在使用 read -n 1 -s -r -p '',然后根据通过一小组 if 语句传递的用户输入来执行操作。

我需要能够防止用户不小心拖入充当读取命令输入的文件。我非常愿意替换 read 命令,然后允许我防止此用户操作中断进程,但我需要它与大多数 shells 兼容。

现在,正如人们所期望的那样,拖入文件会在终端中输入文件路径,因此 shell 将其视为用户实际按下了键。

我不希望用户能够使用 copy/paste 或拖入文件作为响应阅读提示的方式。

这可能吗?我不介意它是否复杂并且可能不值得;无论如何我都会实施它我确定 :D

我不熟悉官方 shell 名称,但我希望它至少与 Mac OSX 终端和 Ubuntu.[=12 兼容=]

部分回答 (停止用户在文件或目录中拖动,但不从 copy/pasting 拖动)

可能有更可靠、更实用的方法,但我不知道。

受@user1934428 关于清空键盘缓冲区的建议的启发,我遇到了一个 reddit post,其中包括清除缓冲区的 Perl 命令。我做了一些试验和错误,发现这很有效:

read -n 1 -s -r -p '' && perl -e 'use POSIX; tcflush(0, TCIFLUSH);'
while [[ "$REPLY" == *"/"* ]] || [ "$REPLY" = "" ]; do
    read -n 1 -s -r -p '' && perl -e 'use POSIX; tcflush(0, TCIFLUSH);'
done

清除缓冲区后,$REPLY 方便地在文件内存中留下一个“/”,而在目录中留空。

这让我可以使用那个 while 循环来等待,直到用户没有拖入文件或目录,并根据它做不同的事情。

但这并没有解决 copy/paste 问题。

我认为没有办法阻止 Copy/Pasting(或等效的文件拖动)。此服务由 window 管理器提供,不受应用程序控制。

也就是说,考虑使用纯 bash 实现刷新 - 在提示用户输入之前和获取数据之后刷新缓冲区。这可以通过强制读取超时来完成。

该解决方案还将阻止向程序提供来自管道的输入,或 similar/file。我会把它留给 OP 来决定是否需要这样做。

# Read all pending input
while read -t 0.1 ; do : ; done
# Read input
read -n 1 -s -r -p ''
# Consume any remaining input
while read -t 0.1 ; do : ; done