Eu tenho um problema estranho relacionado a grep -v
consultas. Permita-me explicar:
Para exibir as conexões que eu uso 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)
A corrente tty
do meu terminal épts/0
$ tty
/dev/pts/0
$ tty | cut -f3-4 -d'/'
pts/0
Tento excluir minha própria conexão usando grep -v $(tty | cut -f3-4 -d'/')
. A saída esperada deste comando deve ser who
, sem a minha conexão. No entanto, a saída é mais inesperada:
$ who | grep -v $(tty | cut -f3-4 -d'/')
grep: a: No such file or directory
grep: tty: No such file or directory
Eu incluo as $(...)
aspas e isso parece corrigir o problema "Esse arquivo ou diretório não existe". No entanto, minha conexão ainda é impressa, mesmo que meu tty ( pts/0
) devesse ter sido excluído:
$ 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)
A partir deste ponto, não tenho absolutamente nenhuma idéia de por que a grep
consulta está com defeito.
command-line
grep
tty
talvez talvez
fonte
fonte
set -x
em primeiro lugar ... Em seguida, execute o seu comando e ver o que você está realmente tentandogrep
...grep
"não é um tty". Como você sugeriria que eu contornasse isso?Respostas:
Zachary explicou a fonte do problema.
Enquanto você pode contornar isso com
Isso seria errado, por exemplo, se esse tty é
pts/1
, você acabaria excluindo todas as linhas que contêmpts/10
. Algumasgrep
implementações têm a-w
opção de fazer uma pesquisa por palavrasnão corresponderia
pts/10
porque opts/1
in não é seguido por um caractere que não seja palavra.Ou você pode usar
awk
para filtrar o valor exato do segundo campo, como:Se você quiser fazer isso em um comando:
O stdin original está sendo duplicado no descritor de arquivo 3 e restaurado para o
tty
comando.fonte
tty | cut -f3-4 -d'/' | xargs -I % sh -c "who | grep -v %"
Na página de informações tty.
O problema é que, no seu exemplo, o stdin do tty é um pipe, não o seu terminal.
Você pode ver neste exemplo.
Para contornar isso, você poderia fazer algo assim.
Existe uma maneira mais rápida / eficiente, porém requer dois comandos.
fonte
who | grep -v "$(ps ax | grep "^$$" | awk '{ print $2 }')"
produz a saída esperada na minha caixa et=$(tty) who|grep -v "${t:5}"
não produz nada.GNU bash, version 4.1.2
ps ax | grep "^ *$$"
poderia corresponder falsamente, por exemplo, seu shell é 123 e existe 1234;ps ax -otty= $$
é mais robusto e apenas um processo. Mas eu prefiro o seu${t:5}
ou de Stephane${t#/dev/}
(ousubstr(t,6)
)