Tengo un problema extraño relacionado con las grep -vconsultas. 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 ttyde 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 grepconsulta no funciona correctamente.
command-line
grep
tty
quizás pueda
fuente
fuente

set -xprimera ... 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. Algunasgrepimplementaciones tienen la-wopción de hacer una búsqueda de palabrasno coincidiría
pts/10porque la entradapts/1no está seguida de un carácter que no sea de palabra.O puede usar
awkpara 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
ttycomando.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.2ps 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))