Comando para encontrar usuários que não estão logados

2

Existe algum comando que possa encontrar o número de usuários que não estão conectados ao sistema?

Estou tentando gravar um script de shell que conta o número de usuários que estão conectados e o número de usuários que não estão conectados.

    
por Sreyan 06.12.2014 / 05:23

3 respostas

4

Listando grupos de usuários

Você pode obter uma lista de todos os seus usuários locais com este comando:

$ getent passwd | awk -F: '{print $1}'

OBSERVAÇÃO: getent retornará usuários locais supondo que você não tenha sssd (ou algum serviço semelhante em execução que também atrai usuários LDAP) e seu /etc/nsswitch.conf esteja restrito a arquivos, ou seja, não está incluindo coisas como NIS ou NIS +. Somente para usuários locais, você pode recorrer a awk -F: '{print $1}' /etc/passwd .

Uma lista de quem está conectado no momento:

$ who

Uma lista de usuários que atualmente não estão logados:

$ grep -Fxvf <(who | awk '{print $1}' | sort -u) \
    <(getent passwd | awk -F: '{print $1}')

Este último leva a lista de usuários que estão logados e mostra a lista de todos os usuários menos os usuários logados, usando grep -vf .

Obtendo contagens

Para obter contagens, basta levar um wc -l para o final dos comandos.

não logado
$ grep -Fxvf <(who | awk '{print $1}' | sort -u) \
    <(getent passwd | awk -F: '{print $1}') | wc -l
53
logado
$ who | awk '{print $1}' | sort -u | wc -l
1

grep flags

-F, --fixed-strings
        Interpret PATTERN as a list of fixed strings, separated by newlines, 
        any of which is to be matched.

-x, --line-regexp
        Select only those matches that exactly match the whole line.

-v, --invert-match
        Invert the sense of matching, to select non-matching lines.

-f FILE, --file=FILE
        Obtain patterns from FILE, one per line.  The empty file contains 
        zero patterns, and therefore matches nothing.

Usando join em vez de grep

Você também pode abrir mão usando grep e usar join , já que esse tipo de problema é maior na casa do leme de join . Precisamos usar join -v 2 , o que significa que queremos excluir correspondências e mostrar apenas os únicos do nosso segundo argumento, getent ... .

junte-se à página do manual
-a FILENUM
        also print unpairable lines from file FILENUM, where FILENUM is 
        1 or 2, corresponding to FILE1 or FILE2

-v FILENUM
        like -a FILENUM, but suppress joined output lines


$ join -v 2 <(who | awk '{print $1}' | sort -u) \
    <(getent passwd | awk -F: '{print $1}' | sort) | wc -l
53

OBSERVAÇÃO: A única ressalva de usar join é que ambas as listas precisam ser classificadas, por isso, precisamos adicionar um | sort a getent ... .

    
por 06.12.2014 / 06:05
1

Você pode escrever um script que armazene o número de usuários atualmente logados em um arquivo e o total de usuários em outro arquivo e faça um comm sobre eles.

Por exemplo:

#!/bin/bash

w | awk 'NR > 2 {print $1}' | sort > logged.txt #sorted list of logged users
awk -F':' '{ print $1}' /etc/passwd | sort > allusers.txt #sorted list of all users
comm -23 allusers.txt logged.txt #find lines unique to allusers.txt

Espero que ajude.

    
por 06.12.2014 / 05:51
0

Este one-liner funcionará:

grep -Ev $(users | sed 's/ /|/g') /etc/passwd | awk -F: {'print $1'}

Como funciona :

A saída de users | sed 's/ /|/g' fornecerá uma lista separada por | de usuários conectados.

A opção -E com grep nos permitirá usar mais de uma string (na condição OR) para corresponder. A opção -v imprimirá o que não corresponde a determinadas strings / padrão. A combinação de -E e -v juntos listará todas as linhas que não contêm as cadeias separadas por pipe da saída de users | sed 's/ /|/g' . No final, use awk para filtrar apenas os nomes de usuários.

    
por 06.12.2014 / 18:06