LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Desktop
User Name
Password
Linux - Desktop This forum is for the discussion of all Linux Software used in a desktop context.

Notices


Reply
  Search this Thread
Old 10-27-2021, 08:44 PM   #1
Faki
Member
 
Registered: Oct 2021
Posts: 574

Rep: Reputation: Disabled
Alternative to eval


I am using getopt and setting `eval set -- "$opts"`. I find that most times `eval` is discouraged. What can I use instead?

opts=$( getopt -o "$shortopts" -l "$longopts" -n "${0##*/}" -- "$@" )
eval set -- "$opts"

Last edited by Faki; 10-28-2021 at 09:03 PM.
 
Old 10-27-2021, 10:23 PM   #2
wpeckham
LQ Guru
 
Registered: Apr 2010
Location: Continental USA
Distribution: Debian, Ubuntu, RedHat, DSL, Puppy, CentOS, Knoppix, Mint-DE, Sparky, VSIDO, tinycore, Q4OS, Manjaro
Posts: 5,762

Rep: Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763
I assume, as is the most common case, that you are using the BASH shell.
#1 For integer operations you can use the built-in bash mathematics capability. This is adequate for all integer operations without calling any external binary. (See https://www.linuxscrew.com/bash-math-arithmetic for example and a more detailed and educational discussion at https://www.shell-tips.com/bash/math...c-calculation/.)

#2 for doing floating point operations you can use the printf built-in as documented in the second article referenced above, or call the bc external.
 
Old 10-27-2021, 10:52 PM   #3
Faki
Member
 
Registered: Oct 2021
Posts: 574

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by wpeckham View Post
I assume, as is the most common case, that you are using the BASH shell.
#1 For integer operations you can use the built-in bash mathematics capability. This is adequate for all integer operations without calling any external binary. (See https://www.linuxscrew.com/bash-math-arithmetic for example and a more detailed and educational discussion at https://www.shell-tips.com/bash/math...c-calculation/.)

#2 for doing floating point operations you can use the printf built-in as documented in the second article referenced above, or call the bc external.
The question is about an alternative to `eval` though.
 
Old 10-28-2021, 01:17 AM   #4
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
Quote:
Originally Posted by Faki View Post
The question is about an alternative to `eval` though.
I think the point is that you probably do not need eval at all to achieve what you want.

I do not quite understand your code example:
Code:
eval set -- "$opts"
What's the context?
What's in $opts?
Not saying there isn't one, but currently I cannot imagine a situation where a line like this would make any sense.
 
Old 10-28-2021, 01:22 AM   #5
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
^What ondoho said.

Usually, just omitting the quotes would have the same effect:
Code:
set -- $opts
 
Old 10-28-2021, 08:52 AM   #6
wpeckham
LQ Guru
 
Registered: Apr 2010
Location: Continental USA
Distribution: Debian, Ubuntu, RedHat, DSL, Puppy, CentOS, Knoppix, Mint-DE, Sparky, VSIDO, tinycore, Q4OS, Manjaro
Posts: 5,762

Rep: Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763
Quote:
Originally Posted by Faki View Post
The question is about an alternative to `eval` though.
The articles I referenced discuss eval and note that it is obsolete, and discuss what to do instead.
Perhaps reading one or both would help you.
 
Old 10-28-2021, 10:42 AM   #7
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
@wpeckham. You confused eval with expr. The articles don't mention eval at all.
 
Old 10-28-2021, 12:20 PM   #8
wpeckham
LQ Guru
 
Registered: Apr 2010
Location: Continental USA
Distribution: Debian, Ubuntu, RedHat, DSL, Puppy, CentOS, Knoppix, Mint-DE, Sparky, VSIDO, tinycore, Q4OS, Manjaro
Posts: 5,762

Rep: Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763Reputation: 2763
Quote:
Originally Posted by shruggy View Post
@wpeckham. You confused eval with expr. The articles don't mention eval at all.
Curses (not ncurses), you are right and I was in error in that. Let me get back with better information.

Quote:
eval on the other hand catenates the parameters together to a single string (using one space as a separator between those strings), then treats this resulting string as a new command where the usual expansion and word splitting mechanism of bash are applied, and finally runs this command.
Quote:
There's more to this problem than meets the eye. We'll start with the obvious: eval has the potential to execute "dirty" data. Dirty data is any data that has not been rewritten as safe-for-use-in-situation-XYZ; in our case, it's any string that has not been formatted so as to be safe for evaluation.
Thus, it is not unreasonable to use "eval" under conditions where you tightly control or have extensively sanitized the arguments or data in question. the reason to find alternatives to "eval" is that it lends itself to exploits or unintended consequences of unexpected data or argument structures and content. In other words, it is a risk better avoided.

And here I come to the question that should have been the FIRST thing that I asked (shame on me, I should know better!) "What are you using "eval" for?". Followed by "what is the argument/opt data that you are sending, and is it ever not under your direct control?".
 
Old 10-28-2021, 03:13 PM   #9
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,918

Rep: Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035
Quote:
Originally Posted by Faki View Post
I am using getopt and setting `eval set -- "$opts"`. I find that most times `eval` is discouraged. What can I use instead?
"getopts" (with an 's') is what you want. Much nicer and avoids the need for that horrible "eval set ..." mechanism.
 
Old 10-28-2021, 11:21 PM   #10
Faki
Member
 
Registered: Oct 2021
Posts: 574

Original Poster
Rep: Reputation: Disabled
What is the difference between

eval set -- "$opts"

and a direct call using

set -- "$opts"
 
Old 10-29-2021, 01:59 AM   #11
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
Code:
eval set -- "$opts"
is roughly equivalent to
Code:
set -- $opts
without quotes. But there's a difference, and this is what makes eval so dangerous. Compare
Code:
opts='a b c;echo def';      set -- $opts; echo $3
to
Code:
opts='a b c;echo def'; eval set -- "$opts"; echo $3
Consider what will happen if you don't control the contents of $opts and instead of echo def there's rm -rf /.

Last edited by shruggy; 10-29-2021 at 03:24 AM.
 
1 members found this post helpful.
Old 10-29-2021, 04:03 AM   #12
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,918

Rep: Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035
Quote:
Originally Posted by Faki View Post
What is the difference between

eval set -- "$opts"

and a direct call using

set -- "$opts"
Without the 'eval' the shell will word split in the wrong places.
Code:
$ opts='"-f" "file with a space.txt" "-v"'
$ set -- $opts
$ for opt in "$@" ; do echo $opt ; done
"-f"
"file
with
a
space.txt"
"-v"
$ set -- "$opts"
$ for opt in "$@" ; do echo $opt ; done
"-f" "file with a space.txt" "-v"
$ eval set -- "$opts"
$ for opt in "$@" ; do echo $opt ; done
-f
file with a space.txt
-v
$
as can be seen, 'eval' is required for set to correctly reset the options from the string from getopt.

The issue with eval however is as shruggy describes above: it can be tricked into running commands, e.g.
Code:
$ opts='"-f" "file with a space.txt" "$( date )"'
$ echo $opts
"-f" "file with a space.txt" "$( date )"
$ eval set -- "$opts"
$ for opt in "$@" ; do echo $opt ; done
-f
file with a space.txt
Fri 29 Oct 09:53:52 BST 2021
$
Now, gnu getopt will quote that $( ) to prevent this sort of thing from happening (with a single eval), so it should be safe even with an 'eval', but because of this inherent issue with eval, most script-writers will recoil in horror when seeing one used. Also, not all implementations of getopt will even do this quoting, leaving them vulnerable.

So, in short, with the gnu implementation of getopt and using the -o syntax, you don't need to have any fears about using a single eval, but other implementations of getopt will likely not be safe.

Last edited by GazL; 10-29-2021 at 04:26 AM.
 
1 members found this post helpful.
Old 12-07-2021, 01:11 PM   #13
Franco Walker
LQ Newbie
 
Registered: Oct 2021
Posts: 3

Rep: Reputation: Disabled
I used bash's built-in math capabilities.
 
Old 12-23-2021, 12:30 PM   #14
Franco Walker
LQ Newbie
 
Registered: Oct 2021
Posts: 3

Rep: Reputation: Disabled
Quote:
Originally Posted by GazL View Post
Without the 'eval' the shell will word split in the wrong places.
Code:
$ opts='"-f" "file with a space.txt" "-v"'
$ set -- $opts
$ for opt in "$@" ; do echo $opt ; done
"-f"
"file
with
a
space.txt"
"-v"
$ set -- "$opts"
$ for opt in "$@" ; do echo $opt ; done
"-f" "file with a space.txt" "-v"
$ eval set -- "$opts"
$ for opt in "$@" ; do echo $opt ; done
-f
file with a space.txt
-v
$
as can be seen, 'eval' is required for set to correctly reset the options from the string from getopt.

The issue with eval however is as shruggy describes above: it can be tricked into running commands, e.g.
Code:
$ opts='"-f" "file with a space.txt" "$( date )"'
$ echo $opts
"-f" "file with a space.txt" "$( date )"
$ eval set -- "$opts"
$ for opt in "$@" ; do echo $opt ; done
-f
file with a space.txt
Fri 29 Oct 09:53:52 BST 2021
$
Now, gnu getopt will quote that $( ) to prevent this sort of thing from happening (with a single eval), so it should be safe even with an 'eval', but because of this inherent issue with eval, most script-writers will recoil in horror when seeing one used. Also, not all implementations of getopt will even do this quoting, leaving them vulnerable.

So, in short, with the gnu implementation of getopt and using the -o syntax, you don't need to have any fears about using a single eval, but other implementations of getopt will likely not be safe.
Thanks a lot for the explanation.
 
Old 12-23-2021, 12:39 PM   #15
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,038

Rep: Reputation: 7346Reputation: 7346Reputation: 7346Reputation: 7346Reputation: 7346Reputation: 7346Reputation: 7346Reputation: 7346Reputation: 7346Reputation: 7346Reputation: 7346
Quote:
Originally Posted by Faki View Post
I am using getopt and setting `eval set -- "$opts"`. I find that most times `eval` is discouraged. What can I use instead?

opts=$( getopt -o "$shortopts" -l "$longopts" -n "${0##*/}" -- "$@" )
eval set -- "$opts"
This is the case when you need to use eval. If you wish to omit you need to use something else instead of getopt.
 
  


Reply

Tags
bash, eval, getopt



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
HELP! Installing Live-Eval 8.0 cheekygit Linux - Newbie 6 05-12-2003 05:23 AM
PHP eval() function nxny Programming 2 01-09-2003 02:39 PM
Suse 7.3 eval ramon Linux - General 1 01-19-2002 01:49 PM
suse 7.3 eval install on win2k machine blain Linux - Newbie 6 11-30-2001 01:29 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Desktop

All times are GMT -5. The time now is 10:23 AM.

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