per*_*rry 12 command-line grep tty
我有一个与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)
Run Code Online (Sandbox Code Playgroud)
tty
我的终端的电流是pts/0
$ tty
/dev/pts/0
$ tty | cut -f3-4 -d'/'
pts/0
Run Code Online (Sandbox Code Playgroud)
我尝试使用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
Run Code Online (Sandbox Code Playgroud)
我将$(...)
引号括起来,这似乎解决了“没有这样的文件或目录”问题。但是,即使我的 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)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我完全不知道为什么grep
查询出现故障。
Zac*_*ady 20
从 tty 信息页面。
'tty' 打印连接到其标准输入的终端的文件名。如果标准输入不是终端,它会打印“not a tty”。
问题是在您的示例中,tty 的 stdin 是一个管道,而不是您的终端。
从这个例子中可以看出。
$ tty
/dev/pts/29
$ echo | tty
not a tty
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,你可以做这样的事情。
who | grep -wv "$(ps ax | awk "\$1 == $$ {print \$2}" )"
Run Code Online (Sandbox Code Playgroud)
有一种更快/更有效的方法,但它需要两个命令。
t=$(tty)
who|grep -wv "${t:5}"
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 18
虽然你可以解决它
tty=$(tty)
tty_without_dev=${tty#/dev/}
who | grep -v "$tty_without_dev"
Run Code Online (Sandbox Code Playgroud)
这将是错误的,例如,如果 tty 是pts/1
,您最终会排除所有包含pts/10
. 某些grep
实现可以-w
选择进行单词搜索
who | grep -vw pts/1
Run Code Online (Sandbox Code Playgroud)
将不匹配,pts/10
因为pts/1
in there 后面没有非单词字符。
或者您可以使用awk
过滤第二个字段的确切值,例如:
who | awk -v "tty=$tty_without_dev" '$2 != tty'
Run Code Online (Sandbox Code Playgroud)
如果您想在一个命令中执行此操作:
{ who | awk -v "tty=$(tty<&3)" '$2 != substr(tty,6)'; } 3<&0
Run Code Online (Sandbox Code Playgroud)
原始标准输入被复制到文件描述符 3 并为tty
命令恢复。