Linux - DesktopThis forum is for the discussion of all Linux Software used in a desktop context.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
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.
@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?".
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.