LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   simple script (https://www.linuxquestions.org/questions/linux-newbie-8/simple-script-4175430562/)

suicidaleggroll 10-05-2012 10:50 AM

Quote:

Originally Posted by karentc (Post 4798102)
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.

There's your problem, the formatting in your file is bad.

The output of that command should have looked like this:
Code:

>abennet<
>gwhite<
>jallan<
>csmith<

As I asked before, how did you make this list?

porphyry5 10-05-2012 11:06 AM

I don't know when mapfile was added to bash, I'm using this version
Code:

~/Documents $ bash --version
GNU bash, version 4.1.10(2)-release (i486-slackware-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
~/Documents $

Here's how to do it without mapfile
Code:

~ $ IFS=$'\x0A'
~ $ x=($(cat < fred.txt))
~ $ for ((i=0; i<y; i++)); do chage -l "${x[$i]}" >> cho.txt; done
chage: user 'Root' does not exist in /etc/passwd
chage: user 'q' does not exist in /etc/passwd
~ $ cat cho.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
~ $ IFS=$'\x20'$'\x09'$'\x0A'     
~ $

IFS is bash's Input Field Separator, the value $'\x0A' makes it be only a newline, google ANSI-C quoting
x=($(cat < fred.txt)) creates the array x
you still need to set y as before to the number of items in x, but as I'm using the same terminal its still there for me.
IFS=$'\x20'$'\x09'$'\x0A' resets IFS to its default values, any one of space, tab or newline.

Bash is a delightfully arcane language. If you need a tutorial for it, try http://mywiki.wooledge.org/BashGuide or http://www.grymoire.com/Unix/Sh.html
The second one is a subset of bash, but as a single page it is easy to download and use offline, as it only references itself.

suicidaleggroll 10-05-2012 11:11 AM

I think these suggestions are getting needlessly complex. The problem is the formatting in his file, as evidenced by post #14. More intricate and complicated ways of calling chage which still depend on newline-separated fields in the file aren't going to help matters, because his file is apparently not newline-separated...at least not properly.

We need to go back to the source - how was the file created, and why does it not look like what any of these scripts expect? If that can be resolved, I think almost any of the solutions already posted in this thread will work fine.

Just my thoughts on the matter...

karentc 10-05-2012 01:19 PM

I tried:

for ((i=0; i<y; i++)); do chage -l ${x[$i]} >> test.txt; echo "Above Entry for User ${x[$i]}"; done

which produced nothing. Not even an output file. Again I appreciate your help.

porphyry5 10-05-2012 01:37 PM

Quote:

Originally Posted by karentc (Post 4798240)
I tried:

for ((i=0; i<y; i++)); do chage -l ${x[$i]} >> test.txt; echo "Above Entry for User ${x[$i]}"; done

which produced nothing. Not even an output file. Again I appreciate your help.

Then I think you should check the format of your input file, as others have suggested. A hex editor (bpe is a command-line hex editor often installed by default) will show you explicitly how each line is terminated. In a unix type file, each line should end with the hex character '0A', e.g.
Code:

~ $ bpe fred.txt

File [1 of 1]: fred.txt                                        Size: 0x00000009

COMMAND:                                              File position: 0x00000000

ADDRESS      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  ASCII
-------------------------------------------------------------------------------
0x00000000  67 0A 52 6F 6F 74 0A 71 0A                        g.Root.q.

? in bpe accesses its help pages

karentc 10-05-2012 02:10 PM

so bpe doesn't exist on my system. The file was created from an ls -l > userlist.txt and then opened in excel, deleted what I didn't want and saved as a text file. Once transferred back, I checked it with vi.

porphyry5 10-05-2012 02:47 PM

Quote:

Originally Posted by karentc (Post 4798286)
so bpe doesn't exist on my system. The file was created from an ls -l > userlist.txt and then opened in excel, deleted what I didn't want and saved as a text file. Once transferred back, I checked it with vi.

vi will also work as a hex editor
Code:

:%!xxd        " enters hex mode
:%!xxd -r            " returns from hex mode


suicidaleggroll 10-05-2012 03:36 PM

Quote:

Originally Posted by karentc (Post 4798286)
so bpe doesn't exist on my system. The file was created from an ls -l > userlist.txt and then opened in excel, deleted what I didn't want and saved as a text file. Once transferred back, I checked it with vi.

Why all those steps? The excel part is almost certainly your problem. Try not to edit linux files in windows if at all possible, Windows likes to take over and mess everything up.

In the mean time, try running "dos2unix userlist.txt", and then re-run the test you did in step 14.

karentc 10-05-2012 03:55 PM

Thanks everyone. I found a post by Ricky_ds that came at the problem from a different angle and I ran that to an output file and I have everything I need. Again I appreciate all your time. Still not sure why this wouldn't work, but I have what I need. Just changed the location of the users and it's all good.

#!/bin/bash

formatDate() {
date +%d"."%m"."%Y -d " $1 day"
}
padr() {
string="$1................................................"
echo "$string" | cut -c1-$2
}
length() {
length=`echo "$@" | wc -c | cut -c1-8`
length=$(( $length -1 ))
echo $length
}
padl() {
string="................................................$1"
length=`length "$string"`
echo "$string" | cut -c`expr $length - $2`-$length
}

if [ "$#" = "0" ]; then
echo
echo "List of user accounts with password information"
echo "==============================================="
echo `date`
echo
echo "Legend: M=Minimum password age W=Warning in days before exp"
echo " Dis=Account Disabled"
echo "------------------------------------------------------------------------------------------"
echo "Username |Full name |UID |LastChange|M|Max |W|Passwd Exp|Dis |Acct Exp "
echo "----------|-------------------------|-----|----------|-|-----|-|----------|----|----------"
fi

sort /etc/passwd |grep ":/home/" | awk -F":" '{print}' |\
while read line ; do
name=`echo -e $line | awk -F: '{print$1}'`
uname=`cat /etc/shadow | grep -r "^$name:" | awk -F":" '{print}'`
thisuser=`echo -e $uname | awk -F: '{print$1}'`

if [ "$#" = "1" ] && [ "$1" = "$thisuser" ] || [ "$#" = "0" ]; then

a=`echo -e $uname | awk -F: '{print$3}'`
b=`echo -e $uname | awk -F: '{print$4}'`
c=`echo -e $uname | awk -F: '{print$5}'`
d=`echo -e $uname | awk -F: '{print$6}'`
e=`echo -e $uname | awk -F: '{print$7}'`
f=`echo -e $uname | awk -F: '{print$8}'`

uid=`echo -e $line | awk -F: '{print$3}'`
fullname=`echo -e $line | awk -F: '{print$5}'`

now=$(( ($(date +%s) / 86400) ))
pass=$(( $now - $a ))
last=`formatDate -$pass`

if test "$f" != "" ; then
next=$(( $f - $now ))
exp=`formatDate $next`
else
exp=`echo NEVER`
fi

pexpt=$(( $a + $c ))
pexpt=$(( $pexpt - $now ))
pexp=`formatDate $pexpt`

if [ "$#" = "1" ]; then
echo
echo "===Information for user $name==="
echo "Full name: $fullname"
echo "User ID: $uid"
echo "Password last changed: $last"
echo "Minumum password age: $b"
echo "Maximum password age: $c"
echo "Password warning age: $d"
echo "Password expires on: $pexp"
if test "$e" != "" ; then
echo "The account will be disabled *$e* days after expiration"
fi
echo "The account expires on: $exp"
echo
else
name=`padr $name 10`
c=`padl $c 4`
if test "$e" = "" ; then
e="."
fi
e=`padl $e 3`
exp=`padl $exp 9`
fullname=`padr "$fullname" 25`
uid=`padl $uid 4`
echo "$name|$fullname|$uid|$last|$b|$c|$d|$pexp|$e|$exp"
fi
fi

done

chrism01 10-07-2012 07:35 PM

As per suicidaleggroll; that was exactly my reaction as well


All times are GMT -5. The time now is 08:59 AM.