LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 03-03-2012, 05:53 AM   #1
Angel2953
Member
 
Registered: Sep 2005
Location: Poland
Distribution: Debian, Ubuntu
Posts: 38

Rep: Reputation: 16
Perl: Find highest UID between 1000 and 2000


I'm searching a way to get highest UID from /etc/passwd. I've found a nice way to get highest UID but this return 65534 which is for user nobody. How can i modify this to get what i need:

Code:
my $passwd = "/etc/passwd";
my $highestuid = 0;
my @fields;
open(PW,$passwd) or die "Can't open $passwd:$!\n";

while (<PW>){
    @fields = split(/:/);
    $highestuid = ($highestuid < $fields[2]) ? $fields[2] : $highestuid;
}
close(PW);
print "The next available UID is " . $highestuid . "\n";
 
Old 03-03-2012, 06:17 AM   #2
cin_
Member
 
Registered: Dec 2010
Posts: 264

Rep: Reputation: 23
last;

Try an if and a break...

Code:
while (<PW>){
    @fields = split(/:/);
    if ($fields[2] < 2000) {
        $highestuid = ($highestuid < $fields[2]) ? $fields[2] : $highestuid;
    } else { last; } # break while for UIDs greater than 2000
}

Last edited by cin_; 03-03-2012 at 06:20 AM. Reason: gramm`err
 
Old 03-03-2012, 06:34 AM   #3
Angel2953
Member
 
Registered: Sep 2005
Location: Poland
Distribution: Debian, Ubuntu
Posts: 38

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by cin_ View Post
Try an if and a break...

Code:
while (<PW>){
    @fields = split(/:/);
    if ($fields[2] < 2000) {
        $highestuid = ($highestuid < $fields[2]) ? $fields[2] : $highestuid;
    } else { last; } # break while for UIDs greater than 2000
}
This time it returned 41 XD. I think my /etc/passwd isn't sorted by UID but rather the way i added users so it's like this:

Code:
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
#...
testuser:x:1001:1001::/home/testuser:/bin/false
testuser2:x:1002:1002::/home/testuser2:/bin/false
testuser3:x:1003:1003::/home/testuser3:/bin/false
sshd:x:103:65534::/var/run/sshd:/usr/sbin/nologin
bind:x:104:106::/var/cache/bind:/bin/false
mysql:x:105:107:MySQL Server,,,:/var/lib/mysql:/bin/false
messagebus:x:106:109::/var/run/dbus:/bin/false
clamav:x:108:112::/var/lib/clamav:/bin/false
ftpuser:2001:2001::/dev/null:/bin/false
amavis:x:110:114:AMaViS system user,,,:/var/lib/amavis:/bin/sh
postfix:x:107:110::/var/spool/postfix:/bin/false
dovecot:x:109:113:Dovecot mail server,,,:/usr/lib/dovecot:/bin/false
accbackup:2002:2002::/var/backup:/usr/sbin/nologin
vmail:x:5000:5000::/var/vmail:/bin/sh
dkim-filter:x:111:115::/var/run/dkim-filter:/bin/false
tumgreyspf:x:999:65534::/var/lib/tumgreyspf:/bin/false
webmaster:x:2000:2000::/home/webmaster:/bin/bash
 
Old 03-03-2012, 06:51 AM   #4
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371
Hi,

Try this:
Code:
#!/usr/bin/perl

use strict;
use warnings ;

my $passwd = "/etc/passwd";
my $highestuid = 0;
my @fields;
open(PW,$passwd) or die "Can't open $passwd:$!\n";

while (<PW>){
    @fields = split(/:/);
    if ( $fields[2] > 1000 && $fields[2] < 2000 ) {
      $highestuid = ($highestuid < $fields[2]) ? $fields[2] : $highestuid;
    }
}
close(PW);
print "The next available UID is " . $highestuid . "\n";
Hope this helps.
 
1 members found this post helpful.
Old 03-03-2012, 06:53 AM   #5
cin_
Member
 
Registered: Dec 2010
Posts: 264

Rep: Reputation: 23
Yeah, sorry, mine happens to be sorted by UID.

It returned 41 because the else { last; } says that if this value does not satisfy the if statement above then this is the last run to make in the while loop, and being as your /etc/passwd file goes from UID 41 then to UID 65534, and 65534 is greater than 2000, the program thought it was time to break from the while loop immediately after the 41.

Just drop the break and specify your range.

Code:
while (<PW>){
    @fields = split(/:/);
    if ($fields[2] > 1000) && ($fields[2] < 2000) {
        $highestuid = ($highestuid < $fields[2]) ? $fields[2] : $highestuid;
    }
}
NOTE: >1000 and <2000 will not include 1000, and 2000 if there are such values. You would have to use <= or add one to the integer value.

Last edited by cin_; 03-03-2012 at 07:02 AM. Reason: gramm`err
 
Old 03-03-2012, 07:21 AM   #6
Angel2953
Member
 
Registered: Sep 2005
Location: Poland
Distribution: Debian, Ubuntu
Posts: 38

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by druuna View Post
Hi,

Try this:
Code:
#!/usr/bin/perl

use strict;
use warnings ;

my $passwd = "/etc/passwd";
my $highestuid = 0;
my @fields;
open(PW,$passwd) or die "Can't open $passwd:$!\n";

while (<PW>){
    @fields = split(/:/);
    if ( $fields[2] > 1000 && $fields[2] < 2000 ) {
      $highestuid = ($highestuid < $fields[2]) ? $fields[2] : $highestuid;
    }
}
close(PW);
print "The next available UID is " . $highestuid . "\n";
Hope this helps.
Yup worked like a charm XD Thanks
 
Old 03-03-2012, 11:51 AM   #7
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371Reputation: 2371
Hi,

You're welcome

BTW: You do know that this is incorrect?
Quote:
print "The next available UID is " . $highestuid . "\n";

Better would be:
Code:
print "The next available UID is " . ++$highestuid . "\n";
or change next available to highest used
 
Old 03-03-2012, 04:47 PM   #8
Cedrik
Senior Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 2,140

Rep: Reputation: 242Reputation: 242Reputation: 242
Another possible way
Code:
while (<PW>){
    @fields = split(/:/);
    $highestuid = $fields[2] if ($fields[2] =~/1\d\d[1-9]/ and $highestuid < $fields[2]);
}

Last edited by Cedrik; 03-03-2012 at 04:49 PM.
 
Old 03-04-2012, 09:00 AM   #9
Angel2953
Member
 
Registered: Sep 2005
Location: Poland
Distribution: Debian, Ubuntu
Posts: 38

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by druuna View Post
Hi,

You're welcome

BTW: You do know that this is incorrect?


Better would be:
Code:
print "The next available UID is " . ++$highestuid . "\n";
or change next available to highest used
Yes just a typo XD
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
perl script set uid PMP Programming 5 09-12-2011 09:00 PM
Script to find out the UID and GID conflicts cbc Linux - Newbie 2 09-11-2011 02:17 AM
[SOLVED] cannot find username for UID 500 linuxdistroyer Linux - General 3 04-07-2011 03:06 AM
Just finished Vector 6.0 install, know my password, how do I find my UID? NoBoT Linux - Laptop and Netbook 2 08-31-2010 04:56 PM
Monitor/Video Card Setup on Sun Blade 1000/2000 fader Linux - Hardware 0 10-09-2008 01:32 AM


All times are GMT -5. The time now is 03:32 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration