This is almost the exact same question as in this post, except that I do not want to use eval
.
Quick question short, I want to execute the command echo aaa | grep a
by first storing it in a string variable Command='echo aaa | grep a'
, and then running it without using eval
.
In the post above, the selected answer used eval
. That works for me too. What concerns me a lot is that there are plenty of warnings about eval
below, followed by some attempts to circumvent it. However, none of them are able to solve my problem (essentially the OP's). I have commented below their attempts, but since it has been there for a long time, I suppose it is better to post the question again with the restriction of not using eval
.
What I want is a shell script that runs my command when I am happy:
#!/bin/bash
# This script run-this-if.sh runs the commands when I am happy
# Warning: the following script does not work (on nose)
if [ "$1" == "I-am-happy" ]; then
"$2"
fi
$ run-if.sh I-am-happy [insert-any-command]
Your sample usage can't ever work with an assignment, because assignments are scoped to the current process and its children. Because there's no reason to try to support assignments, things get suddenly far easier:
#!/bin/sh
if [ "$1" = "I-am-happy" ]; then
shift; "$@"
fi
This then can later use all the usual techniques to run shell pipelines, such as:
run-if-happy "$happiness" \
sh -c 'echo "$1" | grep "$2"' _ "$untrustedStringOne" "$untrustedStringTwo"
Note that we're passing the execve()
syscall an argv with six elements:
sh
(the shell to run; change to bash
etc if preferred)-c
(telling the shell that the following argument is the code for it to run)echo "$1" | grep "$2"
(the code for sh
to parse)_
(a constant which becomes $0
)untrustedStringOne
contains... (which becomes $1
)untrustedStringTwo
contains... (which becomes $2
)Note here that echo "$1" | grep "$2"
is a constant string -- in single-quotes, with no parameter expansions or command substitutions -- and that untrusted values are passed into the slots that fill in $1
and $2
, out-of-band from the code being evaluated; this is essential to have any kind of increase in security over what eval
would give you.