Discussion:
set and IFS
(too old to reply)
Gérard ROBIN
2018-11-20 10:51:07 UTC
Permalink
Hello,
I encounter a problem when I modify IFS with this file:

cat nomutilsuid.sh

#!/bin/bash

while read nom reste
do
svIFS=$IFS
IFS=:
set $nom
IFS=$svIFS
echo $1 $4
done < modfile

cat modfile

g:gg:ggg:1:bin
q:qq:qqq:2:bin
f:ff:fff:3:bin
k:*:kkk:4:bin

the output of ./nomutilsuid.sh

g 1
q 2
f 3
k danbin.sh

where danbin.sh is the third file of the current directory instead of 4.

The issue rises with the file /etc/passwd
How can we solve the problem ?

tia.
--
Gerard
Pierre Gaston
2018-11-20 11:26:33 UTC
Permalink
Post by Gérard ROBIN
Hello,
cat nomutilsuid.sh
#!/bin/bash
while read nom reste
do
svIFS=$IFS
set $nom
IFS=$svIFS
echo $1 $4
done < modfile
cat modfile
g:gg:ggg:1:bin
q:qq:qqq:2:bin
f:ff:fff:3:bin
k:*:kkk:4:bin
the output of ./nomutilsuid.sh
g 1
q 2
f 3
k danbin.sh
where danbin.sh is the third file of the current directory instead of 4.
The issue rises with the file /etc/passwd
How can we solve the problem ?
IFS is working fine the problem is that the * gets expanded because your
variables are not quoted.
( var=*; echo $var)

Some of the possible fix include:
* read the fields directly: while IFS=: read one two three four rest;do
echo "$one" "$four" ;done
* disable globbing with set -f/set +f
* parse again the line with read
* parse manually with parameter expansion eg ${var##:*}
Gérard ROBIN
2018-11-20 12:35:19 UTC
Permalink
Date: Tue, 20 Nov 2018 13:26:33 +0200
Subject: Re: [Help-bash] set and IFS
IFS is working fine the problem is that the * gets expanded because your
variables are not quoted.
( var=*; echo $var)
* read the fields directly: while IFS=: read one two three four rest;do
echo "$one" "$four" ;done
* disable globbing with set -f/set +f
* parse again the line with read
* parse manually with parameter expansion eg ${var##:*}
Thank you so much.
--
Gerard
Greg Wooledge
2018-11-20 13:19:12 UTC
Permalink
Post by Gérard ROBIN
g:gg:ggg:1:bin
q:qq:qqq:2:bin
f:ff:fff:3:bin
k:*:kkk:4:bin
It seems you are really working with /etc/passwd as your input.
Post by Gérard ROBIN
the output of ./nomutilsuid.sh
g 1
q 2
f 3
k danbin.sh
So the desired output is the username, a space, and the primary GID?
Here's how it should be done in pure bash:

while IFS=: read -r user _ _ gid _; do
printf '%s %s\n' "$user" "$gid"
done < /etc/passwd

It could also be done in awk:

awk -F: '{print $1, $4}' /etc/passwd

You will note that the awk solution is way shorter, and runs faster.
Awk is widely considered the most elegant tool for certain jobs of
this kind.

What really matters is the *final* goal, which you haven't revealed yet.
Loading...