Список всех типов оболочек, используемых пользователями

Я ищу способ перечислить все сеансы, что-то вроде команды who, которая также указала бы тип оболочки, используемой списком пользователей.

1
задан 24 January 2017 в 05:01

3 ответа

Поскольку все установленные оболочки в вашей системе указаны в /etc/shells, вы можете начать оттуда и использовать ps, чтобы указать, какие из них выполняются, и соответствующую информацию.

Итак, сначала получим список оболочек:

$ grep -oP '^/.*/\K.*' /etc/shells | sort -u
bash
csh
dash
fish
ksh
mksh
sh
tcsh
zsh

-o означает «распечатать только соответствующую часть строки», а -P включает PCRE, Perl Compatible Regular Expressions, которые позволяют использовать такие необычные вещи, как \K, что означает «игнорировать все, что соответствует этому моменту». Таким образом, ^/.*/\K.* означает строки соответствия, начинающиеся с / (^/), а затем как можно больше символов до / (.*/), затем забудьте о том, что было сопоставлено до сих пор (\K). и сопоставлять все остальное до конца строки. Это будет эффективно возвращать последнюю часть каждой строки, фактическое имя оболочки (например, bash для /bin/bash).

sort -u просто гарантирует, что никакие оболочки не печатаются дважды (иногда вы можете имеют ту же оболочку как в /bin, так и /usr/bin).

Но мы хотим использовать этот список для поиска вывода ps, поэтому нам нужно его в формате, который grep может понять:

$ grep -oP '^/.*/\K.*' /etc/shells | sort -u | perl -pe '!eof && s/\n/\|/'
bash|csh|dash|fish|ksh|mksh|sh|tcsh|zsh

Что [ f23] просто заменяет символы новой строки (\n) на |, поэтому ее можно напрямую подать на grep.

Теперь мы используем pgrep для перечисления всех процессов сопоставления:

$ pgrep -x "$(grep -oP '^/.*/\K.*' /etc/shells | sort -u | 
    perl -pe '!eof && s/\n/\|/')" 
1235
5399
14031
14116
14200
14304
14337
14392
15257
15368
15551
15601
15704
15877
17033
28177
29138
30797
32404
32656

Требуется -x, чтобы только те процессы, которые точно соответствуют (поэтому нет foosh для [ f30]).

Теперь, когда у нас есть список целевых PID, мы можем передать их в ps и использовать его для печати соответствующей информации:

$ pgrep -x "$(grep -oP '^/.*/\K.*' /etc/shells | sort -u | 
    perl -pe '!eof && s/\n/\|/')" | 
        while read pid; do ps -p $pid -o pid=,cmd=,euser=,tty=; done
 1235 /bin/bash                   terdon   pts/1
 5399 /bin/bash                   terdon   pts/4
12341 /bin/bash                   terdon   pts/2
14031 /bin/bash                   terdon   pts/8
14116 /bin/bash                   terdon   pts/9
14200 /bin/bash                   terdon   pts/10
14304 /bin/bash                   terdon   pts/11
14337 /bin/bash                   terdon   pts/12
14392 /bin/bash                   terdon   pts/13
15257 dash                        terdon   pts/13
15368 zsh                         terdon   pts/12
15551 mksh                        terdon   pts/11
15601 -sh                         terdon   pts/10
15704 -csh                        terdon   pts/9
15877 sh                          terdon   pts/8
17033 /bin/bash                   terdon   pts/2
28177 /bin/bash                   terdon   pts/3
29138 fish                        terdon   pts/3
30797 /bin/bash                   terdon   pts/5
32404 /bin/bash                   terdon   pts/6
32656 /bin/bash                   terdon   pts/7

Это читает каждый PID, созданный предыдущими шагами, и запускает ps для него (-p $pid), используя флаг -o для управления выводом для печати ПИД-кода, используемой командой, пользователя, который запустил его и подключенного к нему терминала к.

2
ответ дан 23 May 2018 в 02:08

Вот сценарий, в котором перечислены PID оболочки, ее двоичный код, терминал, к которому прикреплен stdin оболочки, и имя пользователя владельца процесса. Скрипт широко использует файловую систему /proc для лучшей точности.

Что вы видите на скриншоте ниже, это образец запуска этого скрипта. У меня есть два раскола, открытых с эмулятором терминала Terminator. Число в квадратных скобках каждого приглашения - это PID этой оболочки. Верхний раскол подтверждает, что у меня есть два экземпляра mksh, открытых в виртуальных псевдотерминалах, которые являются терминалами GUI, и один экземпляр bash. Другой экземпляр mksh можно найти в tty1. Интересно также, что есть два экземпляра dash, прикрепленных к /dev/null. Изучая процессы, к которым они принадлежат, выясняется, что они принадлежат одному обсерватору Unity и услуге zeitgeist. Таким образом, в этом скрипте легче увидеть, какие оболочки действительно используются реальными пользователями, а какие - системными процессами.

Источник сценария ниже, а также доступен

#!/usr/bin/env bash

is_self(){

    if [ "$link" == "/bin/bash" ] &&  grep -q $0 /proc/$proc_pid/cmdline
    then
        return 0
    else
        return 1
    fi

}
print_proc_info(){
     terminal=$( readlink -e "/proc/$proc_pid/fd/0" )
     [ -z "$terminal"  ] && terminal=$'\t'
     printf "%s\t%s\t%s\t" "$proc_pid" "$1" "$terminal"
     stat --printf="%U\n" /proc/"$proc_pid"/mountstats 
}

find_process(){
     local function_pid=$$

     local search_base=$(basename "$1")

     find /proc -maxdepth 1 -type d -path "*/[1-9]*" | while read -r proc_dir;
     do
         local proc_pid=$(basename "$proc_dir")
         local link=$(readlink -e "$proc_dir"/exe)
         local name=$( awk 'NR==1{print $2}' "$proc_dir"/status  2>/dev/null )

         if is_self ; then continue ; fi

         if [ "$link" == "$1"   ] ||
            [ -z "$link"  ] && [ "$name" = "$search_base"  ]
         then
             print_proc_info $1
         # make additional check if readlink wasn't allowed to 
         # get where /proc/[pid]/exe is symlinked

         fi
     done

}

main(){
    while read -r shell
    do
        find_process "$shell" 
    done < /etc/shells 

    echo "Done, press [ENTER] to continue"
    read
}

main 
1
ответ дан 23 May 2018 в 02:08

Информация о оболочке с дочерними процессами

ps -efH | egrep 'pts/|tty'

sup      14536  2065  0 17:05 pts/19   00:00:00               bash
sup      14572 14536  0 17:05 pts/19   00:00:00                 dash
sup      14575 14572  0 17:05 pts/19   00:00:00                   bash
sup      14611 14575  0 17:05 pts/19   00:00:00                     dash
sup      14673  1956  0 17:06 pts/6    00:00:00             /bin/bash
sup      14717 14673  0 17:06 pts/6    00:00:00               bash
sup      15650 14717  0 17:16 pts/6    00:00:00                 ps -efH
1
ответ дан 23 May 2018 в 02:08

Другие вопросы по тегам:

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