如何防止用户在 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
我有一个 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