Команда для нахождения пользователей, которые не зарегистрированы

comm(1) инструмент, который сравнивает два списка и может дать Вам пересечение или различие между двумя списками. Списки должны быть отсортированы, но этого легко достигнуть.

Получить Ваши массивы в отсортированный список, подходящий для comm:

$ printf '%s\n' "${A[@]}" | LC_ALL=C sort

Это повернет массив в отсортированный список. Сделайте то же для B.

Использовать comm возвратить пересечение:

$ comm -1 -2 file1 file2

-1 -2 говорит для удаления записей, уникальных для file1 (A) и уникальный для file2 (B) - пересечение двух.

Чтобы иметь его возвращают то, что находится в file2 (B), но не file1 (A):

$ comm -1 -3 file1 file2

-1 -3 говорит для удаления записей, уникальных для file1 и характерных для обоих - отъезд только уникальных для file2.

Подавать два конвейера в comm, используйте функцию "Process Substitution" bash:

$ comm -1 -2 <(pipeline1) <(pipeline2)

Получать это в массиве:

$ C=($(command))

Соединение всего этого:

# 1. Intersection
$ C=($(comm -12 <(printf '%s\n' "${A[@]}" | LC_ALL=C sort) <(printf '%s\n' "${B[@]}" | LC_ALL=C sort)))

# 2. B - A
$ D=($(comm -13 <(printf '%s\n' "${A[@]}" | LC_ALL=C sort) <(printf '%s\n' "${B[@]}" | LC_ALL=C sort)))
2
07.12.2014, 00:21
3 ответа

Можно написать сценарий, в котором будет сохранено количество пользователей, зарегистрированных в данный момент в файле, и общее число пользователей в другом файле, и выполнить над ними comm .

Например:

#!/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
-121--125664-

Вы ошиблись при выводе хотя бы одной команды. Разрешения символьной ссылки всегда имеют значение rwxrwxrwx или вообще не имеют разрешений:

$ touch file
$ ls -l 
total 0
-rw-rw-r-- 1 muru muru 0 Dec  5 20:53 file
$ ln -s file link
$ ls -l 
total 0
-rw-rw-r-- 1 muru muru 0 Dec  5 20:53 file
lrwxrwxrwx 1 muru muru 4 Dec  5 20:53 link -> file
$ chmod a+x file
$ ls -l
total 0
-rwxrwxr-x 1 muru muru 0 Dec  5 20:53 file
lrwxrwxrwx 1 muru muru 4 Dec  5 20:53 link -> file

Дополнительные сведения см. в разделе Часто задаваемые вопросы по FreeBSD .

И так как вы находитесь в Linux, man chmod говорит:

   chmod never changes the permissions of symbolic links; the chmod system
   call cannot change their permissions.  This is not a problem since  the
   permissions  of  symbolic  links  are  never  used.   However, for each
   symbolic link listed on the command line, chmod changes the permissions
   of  the  pointed-to  file.   In  contrast, chmod ignores symbolic links
   encountered during recursive directory traversals.
-121--125670-

Перечисление групп пользователей

Вы можете получить список всех ваших локальных пользователей с помощью этой команды:

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

ПРИМЕЧАНИЕ: getent вернет локальных пользователей при условии, что у вас нет sssd (или аналогичной службы, которая также привлекает пользователей LDAP), и ваш /etc/nsswitch.conf ограничен файлами, т.е. он не включает такие вещи, как NIS или NIS +. Только для локального пользователя можно обратиться к awk -F: '{print $1} '/etc/passwd .

Список пользователей, которые в настоящее время вошли в систему:

$ who

Список пользователей, которые в настоящее время не вошли в систему:

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

Этот последний список берет список пользователей, которые вошли в систему, и показывает список всех пользователей за вычетом зарегистрированных пользователей, используя grep-vf .

Получение счетчиков

Чтобы получить счетчики, просто переведите wc -l в конец команд.

не вошел в систему
$ grep -Fxvf <(who | awk '{print $1}' | sort -u) \
    <(getent passwd | awk -F: '{print $1}') | wc -l
53
вошел в систему
$ 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.

Использование соединения вместо grep

Можно также отказаться от использования grep и использовать join вместо этого, так как этот тип проблемы больше в рулевой рубке join . Нам нужно будет использовать join -v 2 , что означает, что мы хотим исключить совпадения и показать только уники из нашего второго аргумента, getent... .

join man page
-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

ПРИМЕЧАНИЕ: Единственное замечание при использовании join состоит в том, что оба списка необходимо отсортировать, поэтому необходимо добавить | sort к getent... .

4
27.01.2020, 21:56

Возможно, вы захотите написать скрипт, в котором будет сохранено количество пользователей, зарегистрированных в настоящее время в одном файле, и общее количество пользователей в другом файле, и сделать над ними комментарий .

Например:

#!/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
1
27.01.2020, 21:56

Этот одноклассник будет работать:

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

Как это работает :

Выход Пользователи |. SED 'S / / | / G' даст вам | разделенный список зарегистрированных пользователей.

Опция -E с GREP позволит нам использовать более одной строки (в или состоянии), чтобы соответствовать. Параметр -V распечатает то, что не соответствует указанным строкам / шаблону. Сочетание --e и -V вместе будет перечислять все строки, которые не содержат трубопроводных строк с выхода пользователей | Sed 'S / / | / G' . В конце применения awk отфильтровать только имена пользователей.

0
27.01.2020, 21:56

Теги

Похожие вопросы