Instead of sourcing he wants to parse the file using readline so he
reads the variable name, then he wants to assign a variable of the same
name.
So, in his code he has something like
readline
... - code to parse the line
Where varname contains the variable name(eg var1), and value contains
the value(eg foo)
--
Jerry Feldman <g...@blu.org>
Boston Linux and Unix
PGP key id:3BC1EB90
PGP Key fingerprint: 49E2 C52A FC5A A31F 8D66 C0AF 7CEA 30FC 3BC1 EB90
> _______________________________________________
> Discuss mailing list
> Dis...@blu.org
> http://lists.blu.org/mailman/listinfo/discuss
>
>
Maybe not the most elegant way, but it works. See below
Matts-MacBook-Pro:temp matt$ cat test1.sh
#!/bin/bash
var1=dog
var2=cat
var3=cow
Matts-MacBook-Pro:temp matt$ cat test2.sh
#!/bin/bash
myvar=`cat test1.sh | grep var2 | cut -d"=" -f2`
echo $myvar
Matts-MacBook-Pro:temp matt$ bash test2.sh
cow
Matthew Shields
Owner
BeanTown Host - Web Hosting, Domain Names, Dedicated Servers, Colocation,
Managed Services
www.beantownhost.com
www.sysadminvalley.com
www.jeeprally.com
Like us on Facebook <http://www.facebook.com/beantownhost>
Follow us on Twitter <https://twitter.com/#!/beantownhost>
_______________________________________________
Discuss mailing list
Dis...@blu.org
http://lists.blu.org/mailman/listinfo/discuss
Sorry, first file should be the follow. That's why the output was wrong.
Matts-MacBook-Pro:temp matt$ cat test1.sh
#!/bin/bash
var1=dog
var2=cow
var3=cat
Readline is a library for that command line apps can use for command
editing and history. It's not part of the shell, and I don't think it can
be used the way you're suggesting.
-b
--
the wages of gin is breath. <anonymous>
> I have not done my homework on this as much as I should.
> A coworker needs to set variable names and values input from another
> file. Normally, I would source that file, but he specifically wants to
> parse the file.
> So, in simple terms, he has a file that has something like:
> var1=foo
>
> Instead of sourcing he wants to parse the file using readline so he
> reads the variable name, then he wants to assign a variable of the same
> name.
> So, in his code he has something like
> readline
> ... - code to parse the line
> Where varname contains the variable name(eg var1), and value contains
> the value(eg foo)
Matt's suggestion calls grep and cut for each variable. This creates a lot of process churn, and will become a slowdown if you have a huge number of variables. But you probably don't.
Are you restricted to Bourne, or can you use BASH?
I know BASH can do fancy string manipulation, but I don't think it's doable in Bourne.
In BASH, i'd do something like this: (assuming I understood your question correctly)
(my input file)
$> cat file
var1=foo
var2=bar
var3=badidea
(my one liner)
$> while read line ; do export ${line%%=*}=${line#*=} ; done < file
refs:
http://linuxgazette.net/18/bash.html
Of course, one has to ask why your co-worker is doing this, and not just sourcing the file.
Also, my example will break if you have an equal sign in your variable name or value name.
-peter
This. Sourcing the file is going to be the fastest and most reliable
way to do it.
--
--Rich P.
What he wants to do is the equivalent of sourcing this code, but he
wants to read it from a file.
#/bin/sh
...
IFS="=" # This is not the correct way, but I'm just using it as an example
read varname varvalue
### In this case varname contains "myvar", and vavalue contains "foo"
But, what he wants to end up with is a variable called "myvar"
containing "foo".
### What he wants to do does not make sense to me when sourcing the file
will work just fine.
And if you're really restricted to Bourne and not Bash, then you have to
use '.', not 'source'.
You can play tricks with 'eval' too if you'd like.
-b
--
character is fate. <heraclitus>
There are lots of options:
#!/bin/sh
# equivalent to sourcing the file
while read LINE
do
eval "$LINE"
done <datafile
#!/bin/bash
# same as above, bash/ksh only
for LINE in $(<datafile)
do
eval "$LINE"
done
#!/bin/sh
# similar, but rejects lines that are not NAME=VALUE or have spaces
# also exports all variables processed
egrep "^[^= ]+=[^= ]+$" datafile|while read LINE
do
eval "export $LINE"
done
You could easily parse out the name and value separately, but there's no
reason to, because you're going to end up putting them on either side of
an equal sign in an eval anyways.
-Chris
I believe eval is susceptible to the same risks as source.
I think 'declare' might be what you were looking for, although AFIACT it's not part of Bourne. But this works with BASH when invoked as 'sh'. (Note needing to reset IFS midstream so that declare doesn't throw away the = it needs..)
[root@kressin01v ~]# cat myvars
var1=foo
var2=bar
var3=baz
[root@kressin01v ~]# cat readvar.sh
#!/bin/sh
#
OLDIFS="$IFS"
IFS="="
echo "BEFORE"
echo "====="
set | grep "^var"
echo "====="
while read myvar myvalue
do
echo "$myvar: $myvalue"
IFS="$OLDIFS"
declare $myvar="$myvalue"
IFS="="
done
echo "AFTER"
echo "====="
set | grep "^var"
echo "====="
echo "var1: $var1"
echo "var2: $var2"
echo "var3: $var3"
[root@kressin01v ~]# cat myvars | ./readvar.sh
BEFORE
=====
=====
var1: foo
var2: bar
var3: baz
AFTER
=====
var1=foo
var2=bar
var3=baz
=====
var1: foo
var2: bar
var3: baz
[root@kressin01v ~]#
I could see this (rather than sourcing directly) being potentially useful if you didn't know what variables would be in the file and wanted to keep a list or something without rereading the file. Though there are surely better / less kludgy ways of accomplishing that particular goal as well.
-Dan
You pretty well have to politely inform this person that he's an idiot. You could do something like this:
for line in `cat file.txt`; do
eval ${line}
done
Which has the "benefit" of roughly duplicating source in slow motion. You can't do it with readline because the assignment fails. bash won't use an environment variable as a variable name, at least not directly:
$ foo=bar
$ ${foo}=baz
bash: bar=baz: command not found
"Prevent malicious code"? It's a shell script. Use the Mk.I Eyeball. Because I can stuff malicious code into an "x=y" statement that matches his egrep without any difficulty at all:
foo="`rm -rf *`"
Here's a reasonable method, snipped from some
scripts I wrote a while back. Hope it helps...
USAGE="FIX ME"
parse_config()
{
case "$1" in
ip_addr=*) ip_addr="${1#*=}";;
netmask=*) netmask="${1#*=}";;
dns_srv1=*) dns_srv1="${1#*=}";;
dns_srv2=*) dns_srv2="${1#*=}";;
dns_dom=*) dns_dom="${1#*=}";;
*) echo $USAGE >&2; exit 1;;
esac
}
print_config()
{
echo "ip_addr=$ip_addr"
echo "netmask=$netmask"
echo "dns_srv1=$dns_srv1"
echo "dns_srv2=$dns_srv2"
echo "dns_dom=$dns_dom"
}
while read line
do
parse_config "$line"
done < "$config_file"
# Here is some test output, given the input:
ip_addr=1.2.3.4
dns_srv1=1.2.3.1
$ config_file=/tmp/fubar bash /tmp/parse.ksh
ip_addr=1.2.3.4
netmask=
dns_srv1=1.2.3.1
dns_srv2=
dns_dom=