Search code examples
linuxbashshellheredoc

Define environment variable in a subshell with heredoc


Background: testing a bash script inside a pod where default user does not have sudo rights so that user cannot user vim or nano to create a .sh file so I have to find a way around with cat << EOF >> test.sh. I am doing some local test to make sure it's working properly first. Locally I am creating a file test.sh with nano. See below

#!/bin/bash
# test.sh
VAR="Test"
echo $VAR

When I cat it:

#!/bin/bash
# test.sh
VAR="Test"
echo $VAR%  

I save test.sh , made it execuatble chmod +x test.sh and ran it with ./test.sh The output:

Test

Now when I try to mimic the same behavior in a bash heredoc instead this is the command I use:

cat <<EOF >> test.sh
#!/bin/bash
# test.sh
VAR="Test"
echo $VAR
EOF

I saved it and made it execuatble as well. The cat output is:

#!/bin/bash
# test.sh
VAR="Test"
echo 

So obviously running it wouldn't work. The output null. I think the issue I am facing is that the environment variable $VAR is not defined properly inside the subshell using heredoc.


Solution

  • When you write this:

    cat <<EOF >> test.sh
    #!/bin/bash
    # test.sh
    VAR="Test"
    echo $VAR
    EOF
    

    ...that $VAR is expanded by your current shell (just like writing something like echo "$VAR"). If you want to suppress variable expansion inside your heredoc, you can quote it (note the quotes around 'EOF'):

    cat <<'EOF' >> test.sh
    #!/bin/bash
    # test.sh
    VAR="Test"
    echo $VAR
    EOF
    

    This inhibits variable expansion just like single quotes (echo '$VAR').