假设我想在一个大文件中搜索一个字符串:grep foo bar.txt | less
,但我实际上输入了grep foobar.txt | less
。现在,grep
正在等待我在终端上输入一些内容。看来这个命令一直持续着,直到我注意到我的错误。
shell(任何 shell,或者可能是 tmux)可以检测到命令正在等待控制台输入,并警告我吗?
编辑:似乎每个进程都有一个标准输入,并且 shell 无法知道它是否实际上正在等待某些东西到达那里。然而,shellzsh
知道常见命令的命令行参数grep
,因此可以警告我它所知道的程序。
(grep f
Tab不尝试完成任何内容,grep foo b
Tab将尝试完成文件名。)
答案1
如果您知道您永远不会使用grep
从终端读取数据,则可以将 grep 重新定义为:
grep() {
if [ -t 0 ]; then
< /dev/null command grep "$@"
else
command grep "$@"
fi
}
这不会给你任何关于你的打字错误的警告。但至少它会立即返回而不匹配。当-
或/dev/stdin
作为参数传递给 时,它也会影响行为grep
。
编辑:
实际上,获得警告的一种方法是关闭标准输入,而不是从以下位置重定向它/dev/null
:
grep() {
if [ -t 0 ]; then
<&- command grep "$@"
else
command grep "$@"
fi
}
$ grep foobar.txt
grep: (standard input): Bad file descriptor
答案2
不,因为 shell 无法知道程序是否阻塞输入。即使是这样,它也无法知道输入最终是否会到来(请参阅停机问题)。如果它期待来自终端的输入怎么办?您可以等待几分钟、几天、几十年才能给出它正在等待的输入。less
碰巧阻止输入到达grep
,但情况并非总是如此,例如 try cat | grep foo
- 它将处理您在命令行上键入的内容(Ctrl+D完成)。