我有一个与查询相关的奇怪问题grep -v
。请允许我解释一下:
要显示连接,我使用who
:
$ who
harry pts/0 2016-12-08 20:41 (192.168.0.1)
james pts/1 2016-12-08 19:28 (192.168.0.1)
timothy pts/2 2016-12-08 02:44 (192.168.0.1)
tty
我的终端当前是pts/0
$ tty
/dev/pts/0
$ tty | cut -f3-4 -d'/'
pts/0
我尝试使用排除我自己的连接grep -v $(tty | cut -f3-4 -d'/')
。在没有我的连接的情况下,该命令的预期输出应该是who
。然而,输出是最出乎意料的:
$ who | grep -v $(tty | cut -f3-4 -d'/')
grep: a: No such file or directory
grep: tty: No such file or directory
我将其括$(...)
在引号中,这似乎解决了“没有这样的文件或目录”问题。然而,即使我的 tty ( pts/0
) 应该被排除,我的连接仍然被打印:
$ who | grep -v "$(tty | cut -f3-4 -d'/')"
harry pts/0 2016-12-08 20:41 (192.168.0.1)
james pts/1 2016-12-08 19:28 (192.168.0.1)
timothy pts/2 2016-12-08 02:44 (192.168.0.1)
到目前为止,我完全不知道为什么grep
查询出现故障。
答案1
从 tty 信息页面。
'tty' 打印连接到其标准输入的终端的文件名。如果标准输入不是终端,它会打印“not a tty”。
问题是在你的例子中 tty 的标准输入是一个管道,而不是你的终端。
从这个例子就可以看出。
$ tty
/dev/pts/29
$ echo | tty
not a tty
要解决这个问题,你可以做这样的事情。
who | grep -wv "$(ps ax | awk "\$1 == $$ {print \$2}" )"
有一种更快/更有效的方法,但它需要两个命令。
t=$(tty)
who|grep -wv "${t:5}"
答案2
虽然你可以解决它
tty=$(tty)
tty_without_dev=${tty#/dev/}
who | grep -v "$tty_without_dev"
这是错误的,例如如果 tty 是pts/1
,您最终会排除所有包含 的行pts/10
。有些grep
实现可以-w
选择进行单词搜索
who | grep -vw pts/1
不会匹配 on,pts/10
因为pts/1
in There 后面没有非单词字符。
或者您可以使用awk
过滤第二个字段的确切值,例如:
who | awk -v "tty=$tty_without_dev" '$2 != tty'
如果你想用一个命令来完成它:
{ who | awk -v "tty=$(tty<&3)" '$2 != substr(tty,6)'; } 3<&0
原始标准输入被复制到文件描述符 3 上并为tty
命令恢复。