Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

parsing output of UNIX `who` command

by chinamox (Scribe)
on Oct 02, 2006 at 07:58 UTC ( #575843=perlquestion: print w/replies, xml ) Need Help??

chinamox has asked for the wisdom of the Perl Monks concerning the following question:

Greetings again all of you good monks.

I am attempting to set up a very simple Perl app using the 'who' command in Unix.

Basically I want to set up a simple hash using somthing like:

my %who=('who -q');

I would then like then like to set each of the returned usernames as keys for the hash and have the values in the hash show the number of sessions that a user is logged in.

The read out would look something like:

Beckysue is logged in 1 time. Billybob is logged in 3 times. BubbaJoe is logged in 2 times. Saranne is logged in 1 time. <br><br> ect...

I have a strong urge to try the functions keys(%hash) and values(%hash) but I think I also might be haveing problems passing data from that 'who' command.

Thank you in advanced, I am trying to learn Perl from my home in Beijing with very limited help in meatspace. I have been ramming my head into the desks for the last few hours and the this is upseting the little old lady nextdoor. If anyone can offer a hint, you would be my hero for the day (or night).

2006-10-02 Retitled by planetscape, as per Monastery guidelines

( keep:0 edit:7 reap:0 )

Original title: 'Perl in Unix question'

Replies are listed 'Best First'.
Re: parsing output of UNIX `who` command
by gellyfish (Monsignor) on Oct 02, 2006 at 09:21 UTC

    As an alternative to parsing the output of the external command you might consider using Sys::Utmp:

    use Sys::Utmp; + my $utmp = Sys::Utmp->new(); + my %users; + while ( my $utent = $utmp->getutent() ) { if ( $utent->user_process ) { $users{$utent->ut_user}++; } } + $utmp->endutent; + foreach my $user (keys %users) { printf "%s is logged in %d times\n", $user, $users{$user}; }


      You are a saint among monks. Thank you.
Re: parsing output of UNIX `who` command
by shmem (Chancellor) on Oct 02, 2006 at 08:12 UTC
    You could read the output of who via backticks as one long string with embedded newlines:
    my $str = `who`;

    To get a hash of it, you'd have to split the string on newlines, then split each line:

    foreach my $line (split /\n/,$str) { my ($user, $remainder) = split /\s/,$_,2; $hash{$user}++; # just increment the value }

    But you could also use open to read from who:

    open(PIPE,"who |") or die "Can't run 'who': $!\n"; while(<PIPE>) { my ($user, $remainder) = split; # implicit split splits $_ on /\s ++/ $hash{$user}++;

    Now you have a populated hash.

    # sort by user foreach my $user(sort keys %hash) { print "$user logged in $hash{$user} times.\n"; } # sort by times users are logged in foreach my $user(sort {$hash{$a} <=> $hash{$b}} keys %hash) { print "$user logged in $hash{$user} times.\n"; }


    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: parsing output of UNIX `who` command
by spadacciniweb (Curate) on Oct 02, 2006 at 08:39 UTC
    #!/usr/bin/perl use warnings; use strict; my $who = `who -q`; if ($who =~ /(.+)\n# users/) { $who = $1; } my @who = split / /,$who; my %who; foreach $_ (@who) { $who{$_}++; } foreach $_ (keys(%who)) { print $_, ' is logged ', $who{$_}, " times\n"; }
Re: parsing output of UNIX `who` command
by Anonymous Monk on Oct 02, 2006 at 09:21 UTC
    Given that backticks in list context return a list of lines, and each line starts with the username (which you want to use as a key), I'd do something like:
    my %who; foreach my $user (`who`) { $user =~ /^(\S+)/ or next; $who{$1}++; } while (my($user, $count) = each(%who)) { print "$user is logged in $count time"; print $count == 1 ? ".\n" : "s.\n"; }
    who -q just gives the total number of users logged in on my system, so that's not very useful for counting how often each user is logged in.
      On Solaris who -q gives one or more lines of space-separated user names followed by a summary line giving total no. of users. I wonder what o/s chinamox is using.



        Not on my Solaris.
        $ uname -a SunOS mybox 5.8 Generic_108528-15 sun4u sparc SUNW,UltraAX-i2 $ /usr/bin/who -q anomonk root # users=2 $
Re: parsing output of UNIX `who` command
by cephas (Pilgrim) on Oct 02, 2006 at 12:42 UTC
    Since it the question is already answered well, I'll answer small.

    who|perl -e'$x{(split)[0]}++for(<>);print"$k => $v\n"while($k,$v)=each%x'


      perl -le'$x{(split)[0]}++for(`who`);print"$k => $v"while($k,$v)=each%x +'


      who|perl -lane'$x{$F[0]}++;END{print"$k => $v"while($k,$v)=each%x}'
      who|perl -nle '/ /,$x{$`}++}{print"@l"while@l=each%x'


        who|perl -nle'/ /,$;{$`}++}{print"@l"while@l=each%'
        who|perl -ne'/ /,$;{$`}++}{print$_,$/^="*"for%'

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://575843]
Approved by davido
Front-paged by diotalevi
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (2)
As of 2023-03-21 07:30 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (59 votes). Check out past polls.