假设我在 GUI 文本编辑器中有一个“Quick&Dirty”Perl 脚本,并且在运行 Bash 的终端窗口中启动 Perl 解释器。我可以将 Perl 脚本复制粘贴到终端并按 CTRL-D 使用 Perl 执行它。 Perl 将解释该脚本并执行它。
有时,脚本中存在拼写错误,这会导致 Perl 打印致命错误并退出,但剩余的复制粘贴文本会传递给尝试执行该文本的 Bash shell;要么失败(幸运的情况),要么执行但会做一些不同的事情(不幸的情况)。
例如:在 Bash Prompt 中启动 Perl,复制粘贴 5 行脚本:第 1 行和第 2 行都很好,但第 3 行使 Perl 异常退出,因此第 4 行和第 5 行由 Bash 执行。
我仅使用 Perl 和 Bash 为例;许多其他交互式工具(例如 Python、fdisk)和其他 shell(例如 zsh、csh)都可能会出现问题
有什么方法可以通知 shell 该文本是复制粘贴输入并且可以忽略吗?
像“如果比用户正常输入的速度快,则忽略”之类的东西?
或者类似“如果进程完成,则在读取下一个 shell 输入之前刷新输入缓冲区”?
[[ 有些工具没有这个问题,例如 MySQL cli 永远不会因输入不当而退出。 ]]
答案1
这不是一个答案,但也许这是一个可以接受的解决方法:
alias p='perl; echo hit control-d again; cat > /dev/null'
然后,如果你的 perl 脚本过早退出,你将把剩余的内容无害地粘贴到 /dev/null ;如果 perl 脚本成功,您将看到友好的提醒并按 control-d 退出捕手cat
。
答案2
除了 Jeff Schaller 的“解决方案/解决方法”之外,正确的解决方案似乎是让环境了解来自发送方和接收方的复制粘贴,这称为“括号粘贴模式”。
从https://cirw.in/blog/bracketed-paste,这里有一个简短的片段来解释更多:
总之:
- 启用括号粘贴: printf "\e[?2004h"
- 等待粘贴开始:您将在 STDIN 上看到 \e[200~。
- 等待粘贴停止:您将在 STDIN 上看到 \e[201~。
- 禁用括号粘贴: printf "\e[?2004l"
它尚未完全适用于 Bash,因此我将接受 Jeff Schaller 的答案,这对我来说效果很好。