Why is this `grep -v` not functioning as expected?
From the tty info page.
'tty' prints the file name of the terminal connected to its standard input. It prints `not a tty' if standard input is not a terminal.
The problem is that in your example tty's stdin is a pipe, not your terminal.
You can see from this example.
$ tty
/dev/pts/29
$ echo | tty
not a tty
To work around that you could do something like this.
who | grep -wv "$(ps ax | awk "\$1 == $$ {print \$2}" )"
There is a faster/more efficient way however it requires two commands.
t=$(tty)
who|grep -wv "${t:5}"
Zachary has explained the source of the problem.
While you can work around it with
tty=$(tty)
tty_without_dev=${tty#/dev/}
who | grep -v "$tty_without_dev"
That would be wrong as for instance if that tty is pts/1
, you would end up excluding all the lines containing pts/10
. Some grep
implementations have a -w
option to do a word search
who | grep -vw pts/1
would not match on pts/10
because the pts/1
in there is not followed by a non-word character.
Or you could use awk
to filter on the exact value of the second field like:
who | awk -v "tty=$tty_without_dev" '$2 != tty'
If you want to do it in one command:
{ who | awk -v "tty=$(tty<&3)" '$2 != substr(tty,6)'; } 3<&0
The original stdin being duplicated onto file descriptor 3 and restored for the tty
command.