为什么这个grep -v无法正常工作?


12

我有一个与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

我将$(...)引号引起来,这似乎可以解决“没有此类文件或目录”的问题。但是,即使pts/0应该排除我的tty(),我的连接仍然会打印:

$ 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查询为什么会出现故障。


4
首先如何使用set -x...然后运行命令,看看您实际上在尝试什么grep...
don_crissti

@don_crissti啊,我明白了;告诉我我实际上是在grep唱“不是tty”。您如何建议我解决这个问题?
也许maybeharry

Answers:


18

Zachary解释了问题的根源。

虽然您可以解决

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

不会匹配,pts/10因为pts/1in后面没有非单词字符。

或者您可以使用awk过滤第二个字段的确切值,例如:

who | awk -v "tty=$tty_without_dev" '$2 != tty'

如果要在一个命令中执行此操作:

{ who | awk -v "tty=$(tty<&3)" '$2 != substr(tty,6)'; } 3<&0

原始的stdin复制到文件描述符3上,并为tty命令恢复。


3
+1用于弄清楚如何在一个命令中执行该操作并指出该错误。
扎卡里·布雷迪

一个以上的班轮:tty | cut -f3-4 -d'/' | xargs -I % sh -c "who | grep -v %"
axxis

20

从tty信息页面。

'tty'打印连接到其标准输入的终端的文件名。如果标准输入不是终端,则输出“ not tty”。

问题在于,在您的示例中,tty的stdin是管道,而不是终端。

您可以从此示例中看到。

$ 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}"

@Christopher您是唯一登录到计算机的人吗?
Zachary Brady

@Christopher,很奇怪。因此,who | grep -v "$(ps ax | grep "^$$" | awk '{ print $2 }')"在我的盒子上产生了预期的输出,却t=$(tty) who|grep -v "${t:5}"什么也没有产生。
Zachary Brady

您正在使用什么shell /版本?GNU bash, version 4.1.2
Zachary Brady

2
ps ax | grep "^ *$$"可能不匹配,例如您的shell是123和1234存在;ps ax -otty= $$更强大,只有一个过程。但我更喜欢您的${t:5}或斯蒂芬${t#/dev/}(或substr(t,6)
dave_thompson_085

1
请不要添加免责声明。虽然意图是值得称赞的,但它们并不能真正帮助答案。如果有人指出您的答案有缺陷,则只需编辑您的答案以纳入更正。
terdon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.