LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices

Reply
 
Search this Thread
Old 09-10-2012, 11:07 AM   #1
fakie_flip
Senior Member
 
Registered: Feb 2005
Location: san antonio, texas
Distribution: Fedora 64 bit RAID0 + LUKS, CentOS (server), Backtrack, Gentoo Hardened
Posts: 1,440

Rep: Reputation: 80
Using eval


I was trying to understand exec and eval. I found this example online that claimed it would give the output of ls and df. However, it did not. Would somebody explain?

Code:
[bullshark@alpha ~]$ ./evalexample.sh
ls
df
[bullshark@alpha ~]$ cat evalexample.sh
#!/bin/bash
for i in ls df
do
    eval myvar="$i"
    echo "$myvar"
done
[bullshark@alpha ~]$
 
Old 09-10-2012, 08:58 PM   #2
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,225

Rep: Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021
This version works
Code:
#!/bin/bash
for i in ls df
do
    eval $i
done
and in fact
Code:
#!/bin/bash
for i in ls df
do
   $i
done

Last edited by chrism01; 09-10-2012 at 08:59 PM.
 
Old 09-11-2012, 02:22 AM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
1) Never, ever use eval unless you know exactly what you are doing. It processes the line twice, expanding variables and command substitutions on the first pass, and executing the resulting command on the second pass. This makes it very easy to insert malicious or improper code that can do damage to your system.

Eval command and security issues
http://mywiki.wooledge.org/BashFAQ/048

The bottom line: "If eval is the answer, you're almost certainly asking the wrong question".


2) exec has two uses.

First, it replaces the current process with a new one; basically switching one command for another. It allows you to do things like first run a shell, do some environment setup work, then switch over to the main program you want to run.

The second use of exec in the shell is to set up file descriptors, as described here:

http://wiki.bash-hackers.org/howto/redirection_tutorial

In short, it has nothing to do with this situation.


3)The code you posted uses a loop to first set a variable to the command names, then uses eval to "parse" the variables and execute the commands.

(Edit: actually, the OP code doesn't execute anything; the evaluated line doesn't create a command substitution environment, so eval really does nothing that the shell doesn't do anyway without it).

It's not only inefficient, non-transparent, and even dangerous, it's also completely unnecessary. Besides variables are for data, not code.

I'm trying to put a command in a variable, but the complex cases always fail!
http://mywiki.wooledge.org/BashFAQ/050

Things like this should properly be done with functions. For example:

Code:
lsdf() { ls ; df ;}	#set up a function that combines the two commands

lsdf			#run the combined command stand-alone

myvar=$( lsdf )		#captures the combined output to $myvar

echo "$myvar"		#print the contents of the variable to the screen
This is assuming you want to do this repeatedly, of course. For a one-off command, skip the function and just capture the command output directly:

Code:
myvar=$( ls ; df )
echo "$myvar"

Last edited by David the H.; 09-11-2012 at 02:36 AM. Reason: as posted
 
Old 09-11-2012, 02:40 AM   #4
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,243
Blog Entries: 15

Rep: Reputation: 233Reputation: 233Reputation: 233
As another rule, it's best to always use eval with a single argument. Remember that that whole single string would be reparsed as another statement so there's no need to separate it into multiple arguments:
Code:
statement='do something radical >\"/path/$somewhere\"'
eval "$statement"
Also, never ever use eval with open variables unless on a very rare exhibition you really intend to use IFS with a different value other than whitespaces, to reparse the contents of the variable to split into multiple arguments. That would be a terrible practice though.
Code:
eval $statement
That is actually what they called evil in eval since it tends to have unexpected syntax error on runtime, but if you could see how things would happen, and know how to place things properly, it won't.

Last edited by konsolebox; 09-11-2012 at 02:56 AM.
 
Old 09-11-2012, 03:18 AM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
Meh, let's keep it simple. Just don't use eval at all. Forget it even exists.

If you can't figure out how to do something without it, come here and let more experienced scripters help you solve it. In the very rare case it actually does require eval, we'll work out how to do it safely.
 
Old 09-11-2012, 05:08 AM   #6
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,243
Blog Entries: 15

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by David the H. View Post
Meh, let's keep it simple. Just don't use eval at all. Forget it even exists.
Sorry but with all respect, I'd disagree with this. You're losing a powerful utility if you do that. Learning how to use it would be better instead. There are far many things that Bash or any shell can't do without using eval, and I know that. If in doubt, I'd give you many examples if you like. There might also be other ways than using but most of the time: (a) There' similar risks with IFS-affected syntax, (b) script would run slower or inefficient, and sometimes require you more lines, and makes things difficult to read. Using externals commands most of the time decrements runtime speed. One example I had ran 20 times or 2000% slower.
 
Old 09-11-2012, 11:39 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
Of course there are uses for eval. I never said that. Nor did I say it was the only feature that carries risk. But it is one of the most serious and should never be taken lightly.

All I'm saying is, as a rule of thumb directed especially towards new scripters, if you think you need it, you are almost certainly wrong. Modern shells like bash in particular have features like associative arrays that make eval almost completely superfluous. And in those rare cases where the situation does require it, you need to be sure to do it right.

It's much safer overall for the inexperienced to simply assume up-front that they don't need it, to pretend that it doesn't exist, and ask for help when they are struggling. Let the experts judge if it's really necessary, and teach them how to do it correctly if it is. With guidance they will eventually reach a point where they are experienced enough to know what they are doing and can make their own choices, but until then, better safe than sorry.


(BTW, I can think of few things in scripting that are, by their very nature, more complex to read and use than eval. You have to write a command that creates another command, taking care to properly handle all metacharacters in the process, and it only gets worse when it includes uncontrolled variables and other substitutions. The whole thing is a nightmare of non-transparency, which is the main reason it's such a security risk.)
 
Old 09-12-2012, 12:26 AM   #8
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,243
Blog Entries: 15

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by David the H. View Post
Of course there are uses for eval. I never said that. Nor did I say it was the only feature that carries risk. But it is one of the most serious and should never be taken lightly.

All I'm saying is, as a rule of thumb directed especially towards new scripters, if you think you need it, you are almost certainly wrong. Modern shells like bash in particular have features like associative arrays that make eval almost completely superfluous. And in those rare cases where the situation does require it, you need to be sure to do it right.

It's much safer overall for the inexperienced to simply assume up-front that they don't need it, to pretend that it doesn't exist, and ask for help when they are struggling. Let the experts judge if it's really necessary, and teach them how to do it correctly if it is. With guidance they will eventually reach a point where they are experienced enough to know what they are doing and can make their own choices, but until then, better safe than sorry.
Well ok.

Quote:
(BTW, I can think of few things in scripting that are, by their very nature, more complex to read and use than eval. You have to write a command that creates another command, taking care to properly handle all metacharacters in the process, and it only gets worse when it includes uncontrolled variables and other substitutions. The whole thing is a nightmare of non-transparency, which is the main reason it's such a security risk.)
Well I guess it just depend on how the scripter sees it, and how he makes his script. E.g. I make scripts in a modular way, and I'm fond of using functions most of time. Anyhow I already find the scripts I make, whether eval'd, encapsulated in functions, or simplified with unusual methods, easy to read. Anyway, it seems that only examples could tell; but I no longer want to go deeper to that.
 
Old 09-12-2012, 02:20 AM   #9
fakie_flip
Senior Member
 
Registered: Feb 2005
Location: san antonio, texas
Distribution: Fedora 64 bit RAID0 + LUKS, CentOS (server), Backtrack, Gentoo Hardened
Posts: 1,440

Original Poster
Rep: Reputation: 80
Quote:
Originally Posted by David the H. View Post
1) Never, ever use eval unless you know exactly what you are doing. It processes the line twice, expanding variables and command substitutions on the first pass, and executing the resulting command on the second pass. This makes it very easy to insert malicious or improper code that can do damage to your system.

Eval command and security issues
http://mywiki.wooledge.org/BashFAQ/048

The bottom line: "If eval is the answer, you're almost certainly asking the wrong question".
I'm studying for the Linux+ 2nd exam. So if I understand correctly, eval takes a variable's value and executes it as a command.


Quote:
2) exec has two uses.

First, it replaces the current process with a new one; basically switching one command for another. It allows you to do things like first run a shell, do some environment setup work, then switch over to the main program you want to run.
Current process? Would that be the terminal emulator if I launch use it interactively, and the script if non interactively? Switching which commands? And switching between programs, coming back to a main program, how would that be different than using control+z and then typing bg and later fg to get that main program back.
 
Old 09-12-2012, 03:03 AM   #10
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,243
Blog Entries: 15

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by fakie_flip View Post
eval takes a variable's value and executes it as a command.
Not exactly. All that eval does is re-interpret the string argument[s] that's passed on it. Double quotes ("") has its own way of evaluating its contents, and so is the command-line parser. Imagine trying to use echo instead of eval. The one that you'll see in the output is what eval would execute, in a same way if those commands are typed directly without eval. So, eval doesn't really do anything special but evaluate the contents of the arguments passed on it and run it again as another command. Please run 'help eval'. Whatever is said there is what it does, and nothing more than that.

Perhaps to make it more clear, eval is not intended to parse variables; running the command without variables would still work:
Code:
eval eval eval eval echo a

Last edited by konsolebox; 09-12-2012 at 03:05 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
[SOLVED] An eval alternative grail Programming 7 06-14-2012 02:24 PM
OpenSuse Eval xbaez Suse/Novell 10 12-11-2005 01:16 PM
Eval versions? Jongi Suse/Novell 1 09-05-2005 10:01 AM
Professional eval? hkl8324 Suse/Novell 1 06-20-2005 04:51 AM
SUSE 9.2 Eval?? rm6990 Linux - Distributions 3 10-07-2004 06:50 PM


All times are GMT -5. The time now is 10:47 PM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration