IFS on /etc/passwd

If you want to run the below on /etc/passwd file why does it not stop at the end of the first line. At then end of the first line there isn't any :


!/bin/bash
# seven fields from /etc/passwd stored in $f1,f2...,$f7
#
while IFS=: read -r f1 f2 f3 f4 f5 f6 f7
do
 echo "User $f1 use $f7 shell and stores files in $f6 directory."
done < /etc/passwd
lolaferrariAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Gerwin Jansen, EE MVETopic Advisor Commented:
You have a colon as a separator and 7 fields on a line in /etc/passwd, right? So where do you expect it to stop? Your first line should be this btw:

#!/bin/bash
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Gerwin Jansen, EE MVETopic Advisor Commented:
I get nice output like this:

User root use /bin/bash shell and stores files in /root directory.
User bin use /sbin/nologin shell and stores files in /bin directory.
User daemon use /sbin/nologin shell and stores files in /sbin directory.
User adm use /sbin/nologin shell and stores files in /var/adm directory.
User lp use /sbin/nologin shell and stores files in /var/spool/lpd directory.
User sync use /bin/sync shell and stores files in /sbin directory.
User shutdown use /sbin/shutdown shell and stores files in /sbin directory.
User halt use /sbin/halt shell and stores files in /sbin directory.
...
0
TintinCommented:
IFS is the "Internal Field Separator".  It simply sets the character that is used for defining the separator between fields.  

The while loop simply loops until it runs out of data.

If you need to break out of a loop, you can use 'break'.
0
Rowby Goren Makes an Impact on Screen and Online

Learn about longtime user Rowby Goren and his great contributions to the site. We explore his method for posing questions that are likely to yield a solution, and take a look at how his career transformed from a Hollywood writer to a website entrepreneur.

lolaferrariAuthor Commented:
Sometimes you have to set the IFS back to it's default in order that it reads another line from the file in order that it processes the newline. However, you don't have to do this for /etc/passwd and I wondered why. The last line at the end of the first line in /etc/passwd isn't a : but yet it continues to read the next line.
0
ozoCommented:
What do you mean by "last line at the end of the first line" and how would that be relevant to whether the next line is read?
What do you want to do?
If you want to stop at the first line, you can either break out of the loop, or take head -1
Or why loop at all if you don't want more than one line?
0
Gerwin Jansen, EE MVETopic Advisor Commented:
>> but yet it continues to read the next line

It continues because you give it the whole file to process ( < /etc/passwd ). As I mentioned already, you have 7 fields on each line, each separated by the separator you specify (colon).

So the script is behaving the way it is specified. If you mean different behaviour, then you have to give the script less data, like one line only (head -1 /etc/passwd) as suggested above.
0
lolaferrariAuthor Commented:
Hi ozo i'm just trying to parse the whole input file which is a csv. My script only reads the first line in the csv input file and then stops.

I'm stumped with this! I've tried so many variations of reading my inputfile but the script only reads the first line in the file.

I have a input file that looks like this

<hostname>,<os version>,<comment>,<user>
....
fonzy,SunOS 5.10,NOT-CORRECT,izywizzy
.....

read -r and printf seems not to work on this OS so stuck with read and print.


I've read every line in the file and output it to od to see if there was a  new line at the end of every line and there was.
== this example works for the first line in the file but doesn't read any other line from the input file  beyond the first line==

 while IFS=',' read f1 f2 f3 f4;do
OS=$(echo $f2 | awk '{print $1}')
if [[ "$OS" ==  "SunOS ]]; then
do something with $f1 and $f4
else
if [[ "$OS" == "RHEL" ]]; then
do something with $f1 and $f4
done < inputfile

==this example doesn't

cat input | awk -F','  '{print $1 $2 $3 $4}' | while read f1 f2 f3 f4; do
echo "$f1-$f2-$f3-$f4"
if [[ "$f2" == "SunOS" ]]; then
.....

however, the output isn't correct since $2 in the input file has a space in it and the echo output shows the field displayed like this
fonzy-SunOS-5.10-NOT-CORRECT izywizy
0
ozoCommented:
For one thing, you are missing closing " and fi
0
lolaferrariAuthor Commented:
ah the script runs ok - just a typos because I've no access to the server so it's just from memory so syntactically it's correct
0
lolaferrariAuthor Commented:
while IFS=, read f1 f2 f3 f4;do
OS=$(echo $f2 | awk '{print $1}')
echo "$f1 $f2 $f3 $f4"
if [[ "$f2" == "RHEL" ]]; then
do something $OS $f4
else
if if [[ "$f2" == "SunOS" ]]; then
do something $OS $f4
else
if ... [[....
fi
fi
fi
done < inputfile


OIFS=$'\n'
while IFS=, read f1 f2 f3 f4;do
OS=$(echo $f2 | awk '{print $1}')
echo "$f1 $f2 $f3 $f4"
if [[ "$f2" == "RHEL" ]]; then
do something $OS $f4
else
if if [[ "$f2" == "SunOS" ]]; then
do something $OS $f4
else
if ... [[....
fi
fi
fi
IFS=$OIFS
done < inputfile
0
lolaferrariAuthor Commented:
I was trying to understand the logic of why what I try with /etc/passwd works but the same logic doesn't apply if I use another input file which looks the same as /etc/passwd with the exception that the IFS is a comma instead of a :
I'm sorry for the confusion. I still don't understand why the logic of below works for password file when it done work for other files. After it reads the first line in /etc/passwd the last field in password doesn't have a : but yet the while loop goes around to read the next line in the password file. I have a script that uses a different delimiter but it will only read the first line in the file and apparently others have had a similar problem where you have to set the delimiter back to its default. I tried that but it still doesn't work.
while IFS=':' read -r f1 f2 f3 ......;do
.....
....
done < /etc/passwd
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Unix OS

From novice to tech pro — start learning today.