LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-21-2010, 05:52 PM   #1
Paavo
LQ Newbie
 
Registered: May 2006
Posts: 15

Rep: Reputation: 0
Simpler indirect expansion


Hi,

have these variables set like this:

Code:
firewall_ports_tcp_mythtv="3306 6543 6544"
prefix=firewall_ports
application=mythtv
I can get tcp ports for that application like this:

Code:
tmp="${prefix}_tcp_${application}" # optional brackets around application
tcp_ports="${!tmp}" # indirect expansion with exclamation mark
If there a way to do that without using tmp variable?

-Paavo
 
Old 01-21-2010, 06:07 PM   #2
Paavo
LQ Newbie
 
Registered: May 2006
Posts: 15

Original Poster
Rep: Reputation: 0
Should have been using the search better *before* posting...

Code:
tcp_ports="$(eval echo "\$${prefix}_tcp_${application}")"
Sorry for wasting bandwidth, but here it is also for others looking for the same (or similar) thing.

I found severe warnings about eval ("evil") security, is the above line particularly dangerous?

-Paavo
 
Old 01-21-2010, 06:28 PM   #3
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by Paavo View Post
I found severe warnings about eval ("evil") security, is the above line particularly dangerous?
Code:
var="hello; ls"
echo "$var"
eval echo "$var"
Just be careful where your input comes from. You should really only use this if you have a lot of control over the contents of the variable. I'm sure a lot of the concern is about a user typing mynanme; rm -rf * into some unfortunate login prompt, but really, who's going to put eval in something like that? It's more so one can feel comfortable with something like this:
Code:
var="`cat myscript.sh`"
echo "$var"
The default is to disable variable parsing (except whitespace), and eval is there to override it.
Kevin Barry

Last edited by ta0kira; 01-21-2010 at 06:29 PM.
 
Old 01-21-2010, 06:32 PM   #4
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
Is this really intended as Bash, or as POSIX shell (aka are you using "#!/usr/bin/env bash" or "#!/bin/sh")? If it's POSIX shell, then eval's the only way you can accomplish what you want.. I'd rearrange things a little bit to avoid spawning a subshell and make quoting a little bit nicer:
Code:
eval "tcp_ports=\$${prefix}_tcp_$application"
If it's Bash, I'd use arrays instead of a space-delimited list, though for port numbers I suppose it doesn't really make a difference since port numbers obviously can't contain spaces.
 
Old 01-21-2010, 06:58 PM   #5
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
Two things you can do.
1) Control the environment and PATH variables. You can clear the environment and set the values you need at the start of the script.
2) Use full absolute paths. Not portable, but you could test for the location of programs in the start of the script and assign it to a constant variable. Many service scripts are written this way. It may be important to control the library paths as well.

Code:
#! /bin/sh

### BEGIN INIT INFO
# Provides:          boot.fuse
# Required-Start:
# Should-Start:      boot.udev $local_fs
# Required-Stop:
# Default-Start:     B
# Default-Stop:
# Short-Description: Start and stop fuse.
# Description:       Load the fuse module and mount the fuse control
#       filesystem.
### END INIT INFO

PATH="/sbin:/bin"
...
There are two cases where "#!/usr/bin/env <shell>" can be dangerous.

When the PATH variable includes a path that points to a bad version of the shell which is an suid program.
When the PATH variable includes a path that points to a bad version if the shell and the script is run by the root user.

You might want to look at the manpage for system().
Code:
       The system() function should not be used by programs that have set user (or group) ID privileges. The fork() and exec family of func-
       tions (except execlp() and execvp()), should be used instead. This prevents any unforeseen manipulation of  the  environment  of  the
       user that could cause execution of commands not anticipated by the calling program.
In your example above, you could use:
tcp_ports="$(eval builtin echo "\$${prefix}_tcp_${application}")"

Last edited by jschiwal; 01-21-2010 at 08:11 PM.
 
Old 01-23-2010, 07:11 PM   #6
Paavo
LQ Newbie
 
Registered: May 2006
Posts: 15

Original Poster
Rep: Reputation: 0
Thanks

Nice, easy, clear, simple and short, just like it should be.

-Paavo

PS. I use "#!/bin/bash" - this is a Fedora 12 x86_64 system.

Quote:
Originally Posted by tuxdev View Post
Is this really intended as Bash, or as POSIX shell (aka are you using "#!/usr/bin/env bash" or "#!/bin/sh")? If it's POSIX shell, then eval's the only way you can accomplish what you want.. I'd rearrange things a little bit to avoid spawning a subshell and make quoting a little bit nicer:
Code:
eval "tcp_ports=\$${prefix}_tcp_$application"
If it's Bash, I'd use arrays instead of a space-delimited list, though for port numbers I suppose it doesn't really make a difference since port numbers obviously can't contain spaces.
 
Old 01-24-2010, 12:14 AM   #7
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by tuxdev View Post
Is this really intended as Bash, or as POSIX shell (aka are you using "#!/usr/bin/env bash" or "#!/bin/sh")?
According to my understanding of the env man page, /usr/bin/env bash (without any -* or <NAME>=<VALUE> arguments to env) is functionally equivalent to simply bash. Am I the wrong stick end having?
 
Old 01-24-2010, 12:24 AM   #8
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
In the context of a she-bang, they aren't equivalent. The she-bang does not do a PATH search at all, so if you use "#!bash", it'll try to use a file called "bash" in the current directory as the interpreter. "/usr/bin/env bash" is indeed equivalent to just "bash" on a regular shell prompt.
 
Old 01-24-2010, 01:58 AM   #9
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by tuxdev View Post
In the context of a she-bang, they aren't equivalent. The she-bang does not do a PATH search at all, so if you use "#!bash", it'll try to use a file called "bash" in the current directory as the interpreter. "/usr/bin/env bash" is indeed equivalent to just "bash" on a regular shell prompt.
Thanks; that's illuminating but I still don't understand the benefits of #!/usr/bin/env bash in
Quote:
Originally Posted by tuxdev View Post
Is this really intended as Bash, or as POSIX shell (aka are you using "#!/usr/bin/env bash" or "#!/bin/sh")?
What is the functional difference between #!/usr/bin/env bash and #!/bin/bash (apart from searching $PATH for bash which is not, to my mind, beneficial)?
 
Old 01-24-2010, 02:19 AM   #10
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
You stated the difference. The advantage is portability. Some Distro's or Unix's may have bash or sh located in /bin, one that tends to the ksh may have bash installed in /usr/bin. Your script using "#!/usr/bin/env" will run as long as bash is in the environment.

There are potential dangers. Especially for some BSDs and Unixes where SUID scripts are allowed.
 
1 members found this post helpful.
Old 01-24-2010, 02:54 AM   #11
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by jschiwal View Post
You stated the difference. The advantage is portability. Some Distro's or Unix's may have bash or sh located in /bin, one that tends to the ksh may have bash installed in /usr/bin. Your script using "#!/usr/bin/env" will run as long as bash is in the environment.

There are potential dangers. Especially for some BSDs and Unixes where SUID scripts are allowed.
Thanks jschiwal -- finally I've got it; that's fully clear and useful now
 
  


Reply



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
LXer: GTK+ Indirect Renderer LXer Syndicated Linux News 0 08-05-2008 06:40 AM
Indirect addressing in bash monz Programming 2 11-30-2006 11:58 AM
indirect jmp without `*' when compiling with GPC 3.4.5 Jolle Programming 1 10-30-2006 08:15 AM
Bash indirect reference to array variable(s) sixerjman Programming 6 10-25-2006 11:18 AM
What's wrong with my indirect addressing Annie0716 Programming 0 08-19-2004 10:29 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:27 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
Open Source Consulting | Domain Registration