LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 10-04-2012, 05:44 PM   #1
karentc
LQ Newbie
 
Registered: Oct 2012
Posts: 10

Rep: Reputation: Disabled
simple script


I've used basic linux for a while, really basic. Now I need to write a simple script that will list all my users password status to a file.

I have a list of users (userlist.txt) and need to read that file and do chage -l user.

If you could tell me the steps are doing, it would help me to try other scripts. I'm using bash shell.

Thanks, Karen
 
Old 10-04-2012, 06:19 PM   #2
porphyry5
Member
 
Registered: Jul 2010
Location: oregon usa
Distribution: Slackware 14.1, Arch
Posts: 443

Rep: Reputation: 21
Quote:
Originally Posted by karentc View Post
I've used basic linux for a while, really basic. Now I need to write a simple script that will list all my users password status to a file.

I have a list of users (userlist.txt) and need to read that file and do chage -l user.

If you could tell me the steps are doing, it would help me to try other scripts. I'm using bash shell.

Thanks, Karen
If you enter 'chage' at the command line, it tells you this about its usage
Code:
~ $ chage
Usage: chage [options] [LOGIN]

Options:
  -d, --lastday LAST_DAY        set date of last password change to LAST_DAY
  -E, --expiredate EXPIRE_DATE  set account expiration date to EXPIRE_DATE
  -h, --help                    display this help message and exit
  -I, --inactive INACTIVE       set password inactive after expiration
                                to INACTIVE
  -l, --list                    show account aging information
  -m, --mindays MIN_DAYS        set minimum number of days before password
                                change to MIN_DAYS
  -M, --maxdays MAX_DAYS        set maximim number of days before password
                                change to MAX_DAYS
  -W, --warndays WARN_DAYS      set expiration warning days to WARN_DAYS

~ $
To do what you ask wouldn't need a formal script, just this command
Code:
chage -l < '/path/to/userlist.txt'
where 'chage -l' shows account aging information
< means following string is your input file path
Quotes on the file path are necessary only if it includes embedded whitespace (spaces, tabs, newlines), and may be single or double in this case
/path/to/ is the path to the directory containing the file of user names, not needed if that is the current directory
And it would show out put like this
Code:
~ $ chage -l g       
Last password change                                    : Jun 04, 2012
Password expires                                        : never
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 0
Maximum number of days between password change          : 99999
Number of days of warning before password expires       : 7
~ $
for each user name in userlist.txt (g is my user name)
To send the output to a file instead of printing it on the console, instead use the command as
Code:
chage -l < '/path/to/userlist.txt' > '/path/to/chageoutput.txt'

Last edited by porphyry5; 10-04-2012 at 06:26 PM.
 
Old 10-04-2012, 06:35 PM   #3
karentc
LQ Newbie
 
Registered: Oct 2012
Posts: 10

Original Poster
Rep: Reputation: Disabled
I did as you suggested. But received the following results. Maybe I'm missing something?
# chage -l < '/tmp/userlist.txt > '/tmp/output.txt'
>
>
>
 
Old 10-04-2012, 06:37 PM   #4
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,258

Rep: Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947
You're missing a single quote after userlist.txt

The > prompt is the shell waiting for you to finish the command. It has only encountered three quotes so far, it's expecting a fourth. You can use Ctrl+C to cancel the command, then you can fix it and run it again.
 
Old 10-04-2012, 06:41 PM   #5
karentc
LQ Newbie
 
Registered: Oct 2012
Posts: 10

Original Poster
Rep: Reputation: Disabled
Sorry, missed that, but this is what I had when I first tried feeding the file in and then outputting.

chage -l < '/users/userlist.txt' > '/tmp/results.txt'
Usage: chage [-l] [-m min_days] [-M max_days] [-W warn]
[-I inactive] [-E expire] [-d last_day] user
#
 
Old 10-04-2012, 06:45 PM   #6
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,258

Rep: Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947
Yeah it looks like chage doesn't like that syntax. Try this
Code:
while read user; do echo $user; chage -l $user; done < /users/userlist.txt > /tmp/results.txt
Or in script form:
Code:
while read user; do
   echo $user
   chage -l $user
done < /users/userlist.txt > /tmp/results.txt

Last edited by suicidaleggroll; 10-04-2012 at 06:46 PM.
 
Old 10-04-2012, 06:57 PM   #7
karentc
LQ Newbie
 
Registered: Oct 2012
Posts: 10

Original Poster
Rep: Reputation: Disabled
This is giving the results that prompted me to post this question. But I do appreciate the help. The data in the results.txt file is the same listing that is in the userlist.txt. So it's just outputting the file it read.

# while read user; do echo $user; chage -l $user; done < /users/userlist.txt > /tmp/results.txt
chage: unknown user: abennet
chage: unknown user: gwhite
chage: unknown user: jallan
chage: unknown user: csmith
#
 
Old 10-04-2012, 07:13 PM   #8
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,258

Rep: Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947
It's just outputting the same file it read because apparently none of the users exist on the system, so all you get is the "echo $user" with blank output from the chage -l.

This is how the output should look, if the users actually exist:
Code:
# cat users.txt 
user1
user2
user3
# while read user; do echo $user; chage -l $user; done < users.txt > results.txt
# cat results.txt 
user1
Last password change					: Mar 01, 2010
Password expires					: never
Password inactive					: never
Account expires						: never
Minimum number of days between password change		: 0
Maximum number of days between password change		: 99999
Number of days of warning before password expires	: 7
user2
Last password change					: Jul 02, 2012
Password expires					: never
Password inactive					: never
Account expires						: never
Minimum number of days between password change		: 0
Maximum number of days between password change		: 99999
Number of days of warning before password expires	: 7
user3
Last password change					: Apr 03, 2012
Password expires					: never
Password inactive					: never
Account expires						: never
Minimum number of days between password change		: 0
Maximum number of days between password change		: 99999
Number of days of warning before password expires	: 7
#
 
Old 10-04-2012, 07:25 PM   #9
karentc
LQ Newbie
 
Registered: Oct 2012
Posts: 10

Original Poster
Rep: Reputation: Disabled
I must be doing something incorrectly. I have over 150 users, all exist in the /users/ directory. If I manually do chage -l user1, I get the correct output. But if user1 is in the list /users/userlist.txt, it doesn't output anything, except the name of the user. I've checked for spaces, and there aren't any. I could see one or two typos' in the list, but not all of them.
 
Old 10-04-2012, 09:09 PM   #10
cbtshare
Member
 
Registered: Jul 2009
Posts: 610

Rep: Reputation: 42
try

Quote:
#!/bin/bash

cat user.txt |
while read user;
do

echo Result For user $user Below >>output.txt
chage -l $user >> output.txt
done

Last edited by cbtshare; 10-04-2012 at 09:16 PM.
 
Old 10-04-2012, 10:33 PM   #11
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,258

Rep: Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947
Quote:
Originally Posted by karentc View Post
I must be doing something incorrectly. I have over 150 users, all exist in the /users/ directory. If I manually do chage -l user1, I get the correct output. But if user1 is in the list /users/userlist.txt, it doesn't output anything, except the name of the user. I've checked for spaces, and there aren't any. I could see one or two typos' in the list, but not all of them.
How did you make the list? Maybe it has some weird EOL terminators that are making their way into the chage -l call?
 
Old 10-05-2012, 03:38 AM   #12
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,576
Blog Entries: 31

Rep: Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195
To see if the user names from the file are as expected, what is the output from
Code:
while read -r user; do echo ">$user<"; done < /users/userlist.txt
 
Old 10-05-2012, 11:12 AM   #13
porphyry5
Member
 
Registered: Jul 2010
Location: oregon usa
Distribution: Slackware 14.1, Arch
Posts: 443

Rep: Reputation: 21
Try this approach
Code:
~ $ cat fred.txt
g
Root
q
~ $ mapfile < fred.txt x
~ $ y=${#x[@]}
~ $ for ((i=0; i<y; i++)); do chage -l ${x[$i]}; done
Last password change                                    : Jun 04, 2012
Password expires                                        : never
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 0
Maximum number of days between password change          : 99999
Number of days of warning before password expires       : 7
chage: user 'Root' does not exist in /etc/passwd
chage: user 'q' does not exist in /etc/passwd
~ $
mapfile is a bash internal that creates an array (x) from an input file (fred.txt) using an entire line as the content of each cell. Usually it is used with a '-t' option which omits the newline character from each line when building the array. Without '-t' each cell includes the newline, and I believe it was the lack of this which caused the failure of other methods.
y=${#x[@]} gets the number of cells in array x
The 'for' loop delivers the content of each cell in array x to chage, including the linebreak. That is, it simulates exactly what happens when you enter the username at the console, and press Return.

Mine is a single user machine, so /etc/passwd has only my user entry in it, hence the rejection of Root and q

Following is the 'for' loop rewritten to send chage's output to a file, o.txt. >> is used because we need each user output appended to the file
Code:
~ $ for ((i=0; i<y; i++)); do chage -l ${x[$i]} >> o.txt; done
chage: user 'Root' does not exist in /etc/passwd
chage: user 'q' does not exist in /etc/passwd
~ $ cat o.txt
Last password change                                    : Jun 04, 2012
Password expires                                        : never
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 0
Maximum number of days between password change          : 99999
Number of days of warning before password expires       : 7
~ $
Apparently the non-existent users are being rejected by bash and never presented to chage

And as chage doesn't bother to tell you the user name its dealing with, you might want to make the 'for' loop something like
Code:
for ((i=0; i<y; i++)); do chage -l ${x[$i]} >> o.txt; echo "Above Entry for User ${x[$i]}"; done

Last edited by porphyry5; 10-05-2012 at 11:26 AM.
 
Old 10-05-2012, 11:13 AM   #14
karentc
LQ Newbie
 
Registered: Oct 2012
Posts: 10

Original Poster
Rep: Reputation: Disabled
I copied and pasted your exact line and received
<abennet
<gwhite
<jallan
<csmith

It seems so simple, which is why I'm so stumped. I feel like I'm just missing some obvious typo.
 
Old 10-05-2012, 11:25 AM   #15
karentc
LQ Newbie
 
Registered: Oct 2012
Posts: 10

Original Poster
Rep: Reputation: Disabled
Hmmm, it is a bash shell, but no mapfile found. I'm running Red Hat Enterprise Linux ES release 4 (Nahant Update 7)

While this hasn't solved my problem, I really appreciate the help and this has given me a lot more to work with. Thanks.
 
  


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
Need help getting started simple simple shell script dhonnoll78 Programming 6 12-17-2007 06:34 PM
Simple script to wait for another script Maverick1182 Linux - Newbie 4 11-05-2007 04:45 AM
Iptables (with masq) troubleshooting, very simple script attached script and logs. xinu Linux - Networking 13 11-01-2007 05:19 AM
Need help with a simple script shell script WindowBreaker Linux - Software 2 12-15-2005 01:45 PM
Simple C Shell script is not so simple elconde Programming 2 09-17-2001 12:53 AM


All times are GMT -5. The time now is 12:59 PM.

Main Menu
Advertisement
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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration