I have read a line of bash code from the file, and I want to send it to log. To make it more useful, I'd like to send the variable-expanded version of the line.
I want to expand only shell variables. I don't want the pipes to be interpreted, nor I don't want to spawn any side processes, like when expanding a line with $( rm -r /)
.
I know that variable expansion is very deeply woven into the bash. I hope there is a way to perform just expansion, without any side effects, that would come from pipes, external programs and - perhaps - here-documents.
Maybe there is something like eval
?
#!/bin/bash
linenr=42
line=`sed "${linenr}q;d" my-other-script.sh`
shell-expand $line >>mylog.log
I want a way to expand only the shell variables.
if x=a
, a="example"
then I want the following expansions:
echo $x
should be echo a
.
echo ${a}
should be echo example
touch ${!x}.txt
should be touch example.txt
if [ (( ${#a} - 6 )) -gt 10 ]; then echo "Too long string"
should be if [ 1 -gt 10 ]; then echo "Too long string"
echo "\$a and \$x">/dev/null
should be echo "\$a and \$x>dev/null"
You are absolutely right, it is very dangerous to use the bash. In fact your command suffers from your problem.
Let us discuss your script in detail:
The sed may produce many lines of output, so it is misleading to use the name
line
.Then you did not quote $line, this may have obscure effects:
In this case the pipe is not executed, but passed to the program ls. If you have untrusted input, it is very hard to program a robust shell script.
Using eval is evil - I would never suggest using it, especially for such a purpose!
An alternative way would be in perl, iterate over the $ENV array and replace all env keys by the env values. This way you have more control over the things, which may happen.