This is a simplified version of the problem I'm experiencing just for demonstration purposes. But the command output when it contains a variable reference doesn't seem to go through an evaluation process to populate the variable reference it contains.
So do demonstrate I create a txt file (/mnt/external.txt) with the following line of text "${var1}/filename.txt". I then do a bash script like the following:
#!/bin/bash
var1="/home/user1"
echo $(cat /mnt/external.txt)
This then outputs "${var1}/filename.txt" rather than "/home/user1/filename.txt".
Is there a way to get it to re-evaluate the output of the cat command (just used cat to demonstrate the problem) to have it populate the variable reference with the variable value instead?
CodePudding user response:
You can invoke envsubst
for all of the output of your command, which is something you mentioned in your comments but not your question.
#! /bin/bash
export MYVAR=myval
for i in {0..3}
do
echo "$i: \$MYVAR"
done | envsubst
and the output is
0: myval
1: myval
2: myval
3: myval
CodePudding user response:
You need to pass the returned string thru eval for the substitution to take effect. Your snippet should be modified as follows:
#!/bin/bash
var1="/home/user1"
eval echo $(cat /mnt/external.txt)
CodePudding user response:
This prints what you want, but I agree with Gordon that it's not safe.
#!/usr/bin/env bash
export var1="/home/user1"
echo "$(eval "echo $(< /mnt/external.txt)")"
CodePudding user response:
You can use a heredoc to expand variables and command substitutions only:
eval "
cat <<EOF
$(</mnt/external.txt)
EOF"
Here eval
is used only to print the file external.txt
, so the heredoc can expand it.
This is safer and more predictable than eval "echo '$(<external.txt)'"
(even with quotes). But still open to code injection if external.txt
contained a command sub like $(rm important.txt)
, or the heredoc delimiter:
EOF
rm important.txt
The difference is that it's slightly more predictable than eval echo, where stray quotes and/or list operators (;
|
&
etc) could cause code execution.