1

Consider the following:

$ a='friend'
$ b='printf "%s\n" "$a"'
$ eval "$b"
friend

This should be completely safe. Let's however say that $b is the same but $a is unknown. Are there any security implications then to eval "$b" and if so, what can I do to mitigate them?

6
  • It can be safe as long as the string being evaled is fixed (as it is here), but in that case why bother with eval? On the other hand, if the string is constructed dynamically, you need to take care to constrain how it's constructed to make sure it's safe. Apr 15, 2021 at 10:10
  • @GordonDavisson My thinking is, since I printf the dynamic string then it should be safe regardless of what it contains. Am I wrong in this?
    – fuumind
    Apr 15, 2021 at 10:16
  • 2
  • 1
    a='"; echo "hi' is a negative example.
    – waltinator
    Apr 15, 2021 at 14:25
  • 1
    @waltinator I don't understand. eval "$b" just prints "; echo "hi. I can see how eval "$a" is dangerous though.
    – fuumind
    Apr 15, 2021 at 18:17

1 Answer 1

2

If b contains the literal string printf "%s\n" "$a", i.e. you didn't expand $a into it before hand, then yes, eval "$b" should be fine. Not sure why you'd need eval there, though, since you just have a static command. Just run printf "%s\n" "$a" directly.

You said in comments you want to store some commands for future use. That's the job of functions. E.g. that printf command could be made into a function like this:

println() {
    printf "%s\n" "$1"
}

which you run as println "hello there", println "$a" or whatever. "$1" is the first argument to the function, but of course you could read stdin instead, or use multiple arguments ("$2", "$3", ...; or all of them as a list "$@" (alike "${array[@]}")).

Similarly for the longer set of operations:

#!/bin/bash
say_hi() {
    echo "hello, $1"
}
louder() {
    echo "$1!"
}
funcs=(say_hi louder)
names=(Huey Dewey Louie)
for name in "${names[@]}"; do
    tmp=$name
    for func in "${funcs[@]}"; do
        tmp=$($func "$tmp")
    done
    echo "result: $tmp"
done
1
  • 1
    This way of calling functions is what I need. I was looking for a way out of using a humongous case statement.
    – fuumind
    Apr 17, 2021 at 15:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .