linux - 当完成函数读取文件时,Bash 完成有时会与我的终端相匹配

标签 linux bash shell bash-completion

所以我在使用某些 cli 程序时遇到了问题。有时,当我使用 Ctrl+C 终止正在运行的进程时,它会使终端处于一种奇怪的状态(例如 echo 被关闭)。现在这在很多情况下都是意料之中的,因为终止进程不会给它机会恢复终端的状态。但我发现对于许多其他情况,bash 补全是罪魁祸首。例如,尝试以下操作:

  1. 按如下方式启动新的 bash session :bash --norc 以确保未加载任何补全。
  2. 定义一个完成函数:_completion_test() { grep -q foo/dev/null;返回 1;
  3. 定义一个使用上述函数的完成:complete -F _completion_test rlwrap
  4. 完全键入以下内容:r l w r a p Space c a t Tab Enter(即 rlwrap cat 后跟 Tab,然后是 Enter)。
  5. 稍等片刻,然后使用 Ctrl+C 终止进程。
  6. 终端的 echo 应该没有被关闭。因此,如果您键入任何字符,终端将不会回显。

真正奇怪的是,如果我从完成函数中删除看似无害的grep -q foo/dev/null,一切正常。事实上,将 grep -q foo/dev/null(或者甚至更简单的东西,例如 cat/dev/null)添加到我安装的任何完成函数中系统,导致同样的问题。我还重现了不使用 readline 且没有 Ctrl+C 的程序的问题(例如 find/varTab| head,为find定义了上面的补全)。

为什么会这样?

编辑:澄清一下,上面是一个人为的例子。实际上,我想做的更像是这样:

_completion_test() {
    if grep -q "$1" /some/file; then
        #do something
    else
        #do something else
    fi
}

有关更具体的示例,请尝试以下操作:

_completion_test() {
    if grep -q foo /dev/null; then
        COMPREPLY=(cats)
    else
        return 1
    fi
}

但是我正在调用 grep 这一事实导致了问题。我不明白为什么在这种情况下我不能调用 grep

最佳答案

嗯,这个问题的答案很简单;这是一个bug :

This happens when a programmable completion function calls an external command during the execution of a completion function. Bash saves the tty state after every successful job completes, so it can restore it if a job is killed by a signal and leaves the terminal in an undesired state. In this case, we need to suppress that if the job that completes is run during programmable completion, since the terminal settings at that time are as readline sets them for line editing. This fix will be in the release version of bash-4.4.

关于linux - 当完成函数读取文件时,Bash 完成有时会与我的终端相匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39071003/

相关文章:

python - udemy类(class)ai无法继续安装matplotlib.pyplot

linux - 从文件列表变量中删除所有非目录

Bash 信号捕获未检测到声明 'trap' block 后更改的变量

javascript - Bash 和 mongodb 脚本评估变量

bash - 从名称中带有空格的服务器挂载 SMB 共享

linux - 将 tar.gz 打包成 shell 脚本

java - 为什么 Java 正则表达式在 Linux 和 Windows 上的行为不同?

linux - 如何找到某些文件并将它们复制到文件夹中?

git - 使用 Git 创建跟踪分支的简洁方法

linux - grep 和 AWK 命令读取主机名并打印列