bashshellfilevariable-assignmentvariable-substitution

Bash: Reading in a string from a file with variable substitution


I have a weird situation where I have a command stored in a file and that file contains references to variables.

I'm able to read the file just fine, but I'm having trouble getting variable expansion working.

As a minimum working example, here is a file that contains a command with a variable as an example:

command.in

ls $DIR

simple.sh

#!/bin/bash

MYVAR=$(<command.in)
DIR="/tmp"

$MYVAR

Expected Results

My expected results is that it'll print the contents of /tmp

What I've tried

I've tried moving DIR assignment above MYVAR assignment in simple.sh and I've tried changing the $DIR in command.in to ${DIR} and $(DIR)


Solution

  • $(<command.in) does dereference a variable. You can see what is happening if you put an echo in the script:

    #!/bin/bash
    DIR="/tmp"
    MYVAR=$(<command.in)
    echo $MYVAR
    $MYVAR
    

    which gives:

    bash simple.sh
    ls $DIR
    ls: cannot access '$DIR': No such file or directory
    

    When you do $MYVAR, the variable gets expanded, once. So it produces ls $DIR and that is what is executed. With eval you can force another level of variable expansion:

    #!/bin/bash
    DIR="/tmp"
    MYVAR=$(<command.in)
    echo "$MYVAR"
    eval "$MYVAR"