Посмотрите, кто в настоящее время вошел в систему и получить их информацию из /etc/passwd

Я хотел, чтобы иметь возможность увидеть, кто в настоящее время вошел в систему на сервере, а затем искать /etc/passwd файл на основе их имени пользователя и найти их идентификатор (столбец 3) и полное имя (столбец 5) и отображать их вместе.

Например:

$ who    
USER         TTY
billyt     pts/2 
$ cat /etc/passwd
…
billyt:x:10:100:Tom Billy:/home/billyt:/bin/bash
…

Мой вывод должен отображать его имя пользователя, идентификатор и полное имя:

Username: billyt   ID: 10   FullName: Tom Billy

Это то, что я пробовал до сих пор:

#!/bin/bash
file="/etc/passwd"

while IFS=: read -r f1 f2 f3 f4 f5 f6 f7
do
        # display fields using f1, f2,..,f7
        echo "Username: $f1, UserID: $f3, FullName: $f5"
done <"$file"

Я попытался отобразить нужные мне поля (f1, f3 и f5). Это хороший подход? Смогу ли я просто искать из who сохраните первое поле who (имя пользователя) в who.txt затем искать его из файла выше?

2 ответа

Решение

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

Что-то вроде:

#!/bin/bash

while read -r user throw_away; do 
    users+=( "$user" )
done < <(who)

while IFS=: read -r f1 f2 f3 f4 f5 f6; do
    for name in "${users[@]}"; do
        if [[ "$name" == "$f1" ]]; then
            echo "Username: $f1, UserID: $f3, FullName: $f5"
        fi
    done
done < /etc/passwd 

Мы используем процесс подстановки <(..) передать вывод who к первому while loop и создать массив users, Поскольку нам нужно только имя, мы используем фиктивную переменную throwaway чтобы захватить все остальное.

Во-вторых while loop (Я повторно использовал большую часть вашего существующего кода), мы проверяем, присутствует ли первое поле из `/etc/passwd/ file в нашем массиве. Если это так, мы печатаем строку в желаемом формате.

Вы также можете использовать ассоциативные массивы (bash v4.0 или новее) для хранения пользователей в качестве ключей. Я оставлю это для практики.

Есть, конечно, много способов сделать это.

echo "Username     UserID  Full Name"
while read name therest; do
  g=$(grep "$name" /etc/passwd)
  [[ "$g" =~ ([^:]+):[^:]+:([^:]+):[^:]+:([^:]+) ]]
  printf "%-12s %6d  %s\n" \
         "${BASH_REMATCH[1]}" \
         "${BASH_REMATCH[2]}" \
         "${BASH_REMATCH[3]}"
done < <(who)
Другие вопросы по тегам