Estoy intentando usar awk con la salida de ss para imprimir la cuarta columna. A veces funciona, pero otras veces fusiona o divide las columnas incorrectamente. Probé algunas opciones diferentes para FS, aquí hay dos o más espacios porque los encabezados de los campos contienen un solo espacio.
Esto me da la quinta columna y un encabezado en blanco:
$ ss -tn
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 36 172.31.19.34:22 172.115.128.85:64478
ESTAB 0 0 [::ffff:172.31.19.34]:80 [::ffff:172.115.128.85]:65446
$ ss -tn | awk -F '[[:space:]][[:space:]]+' '{print $4}'
172.115.128.86:64478
[::ffff:172.115.128.86]:65446
El mismo comando aquí me da la cuarta columna, esto es lo que quiero.
$ ss -tn
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 36 172.31.19.34:22 172.115.128.85:64478
$ ss -tn | awk -F '[[:space:]][[:space:]]+' '{print $4}'
Local Address:Port
172.31.19.34:22
Sé cut
que puede ser más fácil, pero lo estoy usando awk
porque quiero realizar un procesamiento adicional.
Para agregar detalles: no estoy seguro de por qué ss muestra esta dirección de estilo IPv6. Esta es una conexión desde mi computadora portátil al servidor Apache, pero mi computadora portátil no tiene una dirección IPv6.
Respuesta1
Comomuruinsinuado en uncomentario, awk
probablemente esté funcionando de manera consistente. Lo que puede variar es el espaciado en la salida de ss
.
Resulta que ss -nt
1 genera siete columnas, cuyos encabezados son: State
, Recv-Q
, Send-Q
, Local Address
, Port
, Peer Address
, Port
. La cuarta y quinta columnas están separadas por dos puntos ( :
); Lo mismo para el sexto y el séptimo. Todos los demás están separados por un carácter de espacio.
Todas las columnas están rellenas con espacios donde sea necesario para la alineación. El cuarto y el sexto están acolchados a su izquierda, todos los demás a su derecha.
Puede ocurrir más relleno:
Si la salida de
ss -nt
se dirige a una terminal:Si la longitud mínima de sus líneas, calculada como la suma del contenido más largo de cada campo más el espacio mínimo (seis caracteres), es menor que el ancho del terminal, cada línea se expande al ancho del terminal mediante un relleno uniforme. todas las columnas con espacios;
de lo contrario, las líneas se dividen y los campos se alinean entre líneas (rellenados como arriba, hasta el ancho del terminal).
Si la salida de
ss -nt
no se dirige a una terminal (por ejemplo, se canaliza o redirige a un archivo normal), la longitud real de las líneas se define como el múltiplo mínimo de 80 que es mayor que la longitud mínima definida anteriormente. Todas las columnas están rellenas uniformemente con espacios para alcanzar una longitud total de línea que, en consecuencia, será de 80, 160, 240, ... caracteres 2 .
Por lo tanto, no hay garantía de que dos columnas estén separadas por dos o más espacios, lo que hace que esa secuencia no sea confiable para la división.
No obstante, puede manejar la salida de ss -tn
de una manera razonablemente segura teniendo en cuenta que los encabezados de las columnas son conocidos y fijos y que, a excepción de los encabezados, ninguna de sus columnas debe incluir espacios 3 :
ss -nt | sed '
1 s/[ ]Address:/_Address|/g # Remove the known spaces from column
# headers; also, change ":" into "|"
s/:\([^:|]*[ ]\)/|\1/g # Change the colons used as separators
# into vertical bars "|", to avoid
s/:\([^:|]*\)$/|\1/g # confusion with those in IPv6s
' | awk -v FS='\\||[ ]+' -v OFS=":" ' # Split on sequences of one or more
{ print $4,$5 } # spaces OR on any vertical bar
'
Esto imprimirá solo la cuarta y quinta columnas (dirección local y puerto), separadas por dos puntos. Tenga en cuenta que, al utilizar un separador de campo que no sea el espacio único predeterminado, awk
se identificarán ocho columnas en lugar de siete y, si hace a { $1=$1; print; }
, imprimirá un OFS
al final de cualquier línea cuya última columna esté rellenada a la derecha con at menos un espacio.
1 Otras opciones (por ejemplo -i
, -e
, -m
) cambian drásticamente la salida de ss
. Por brevedad y claridad, solo nos centraremos en este comando exacto.
2 Aproximado y posiblemente inexacto. Pero esto no es relevante para el objetivo de esta pregunta/respuesta.
3 Al parecer esto no está garantizado, deliberadamente no intentaremos cubrir todos los casos menos habituales.
Respuesta2
¿Por qué el separador de campos awk no funciona de manera consistente?
Lo es, lo que no es confiable es la cantidad de espacios en la salida de ss
.
la cuarta columna, esto es lo que quiero.
Luego simplemente elimine el encabezado ( -H
) y seleccione la cuarta columna:
$ ss -taH | awk '{print $4}'
172.31.19.34:22
[::ffff:172.31.19.34]:80
Como el encabezado está arreglado, simplemente agréguelo nuevamente (si es necesario):
$ echo "Local Address:Port"
Local Address:Port
Comando completo:
$ echo "Local Address:Port"; ss -tnH | awk '{print $4}'
Local Address:Port
172.31.19.34:22
[::ffff:172.31.19.34]:80
Sí, tu computadora siempre tiene direcciones IPv6 (una o varias). Si no las quieres pide sólo las direcciones IPv4:
$ ss -tnH4 | awk '{print $4}'
172.31.19.34:22