Tengo un problema extraño relacionado con las grep -v
consultas. Permítame explicarle:
Para mostrar las conexiones que 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)
La corriente tty
de mi terminal espts/0
$ tty
/dev/pts/0
$ tty | cut -f3-4 -d'/'
pts/0
Intento excluir mi propia conexión usando grep -v $(tty | cut -f3-4 -d'/')
. El resultado esperado de este comando debería ser who
, sin mi conexión. Sin embargo, la salida es más inesperada:
$ who | grep -v $(tty | cut -f3-4 -d'/')
grep: a: No such file or directory
grep: tty: No such file or directory
Adjunto las $(...)
comillas y eso parece solucionar el problema "No existe tal archivo o directorio". Sin embargo, mi conexión todavía se imprime a pesar de que mi tty ( pts/0
) debería haberse excluido:
$ 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 de este punto, no tengo ni idea de por qué la grep
consulta no funciona correctamente.
command-line
grep
tty
quizás pueda
fuente
fuente
set -x
primera ... A continuación, ejecute el comando y ver lo que realmente está tratando degrep
...grep
"no es un tty". ¿Cómo sugerirías que evite esto?Respuestas:
Zachary ha explicado la fuente del problema.
Si bien puedes solucionarlo con
Eso sería incorrecto, por ejemplo, si ese tty es
pts/1
, terminaría excluyendo todas las líneas que lo contienenpts/10
. Algunasgrep
implementaciones tienen la-w
opción de hacer una búsqueda de palabrasno coincidiría
pts/10
porque la entradapts/1
no está seguida de un carácter que no sea de palabra.O puede usar
awk
para filtrar el valor exacto del segundo campo como:Si quieres hacerlo con un solo comando:
El stdin original se duplica en el descriptor de archivo 3 y se restaura para el
tty
comando.fuente
tty | cut -f3-4 -d'/' | xargs -I % sh -c "who | grep -v %"
Desde la página de información de tty.
El problema es que, en su ejemplo, el stdin de tty es una tubería, no su terminal.
Puedes ver en este ejemplo.
Para evitar eso, podrías hacer algo como esto.
Hay una forma más rápida / eficiente, sin embargo, requiere dos comandos.
fuente
who | grep -v "$(ps ax | grep "^$$" | awk '{ print $2 }')"
produce el resultado esperado en mi caja yt=$(tty) who|grep -v "${t:5}"
no produce nada.GNU bash, version 4.1.2
ps ax | grep "^ *$$"
podría falsa coincidencia, por ejemplo, su shell es 123 y 1234 existe;ps ax -otty= $$
es más robusto y solo un proceso. Pero prefiero tu${t:5}
o la de Stephane${t#/dev/}
(osubstr(t,6)
)