Expanding only certain variables inside a heredoc2019 Community Moderator ElectionPassing directory from command line to shell scriptExpanding variables in zshCapturing data from a Fluke 1620a via Bash /dev/tcp file descriptorattempting to put dynamic input data in a variable via cat methodWhat is wrong with my init.d script [Segmentation fault]Variable not expanding inside another variable bashSet variable inside heredoc, use variable outside heredocPreform operation in bash only if a variable is less than a second variableparallel processing reading from a file in a loopCan the ability to overwrite a file with XML be exploited to execute code?Passing directory from command line to shell script

Did Ender ever learn that he killed those two boys?

Tikz: place node leftmost of two nodes of different widths

Do I need to be arrogant to get ahead?

Violin - Can double stops be played when the strings are not next to each other?

Why does the degree of dissociation change when we dilute a weak acid even though the equilibrium constant K is constant?

Do native speakers use "ultima" and "proxima" frequently in spoken English?

How can I wire 7 outdoor posts correctly?

Official degrees of earth’s rotation per day

How to generate binary array whose elements with values 1 are randomly drawn

Can other pieces capture a threatening piece and prevent a checkmate?

Error: "inconsistent hash". Workers crash and node is unable to connect to others

Do US professors/group leaders only get a salary, but no group budget?

Turning a hard to access nut?

Changing Color of error messages

How difficult is it to simply disable/disengage the MCAS on Boeing 737 Max 8 & 9 Aircraft?

T-SQL LIKE Predicate failed to match with whitespace in XML converted varchar

I am trying to parse json data using jq

Why Choose Less Effective Armour Types?

Fragmentation Level for Heaps

Is there a term for accumulated dirt on the outside of your hands and feet?

Worshiping one God at a time?

Regex aa* = a*a?

Light propagating through a sound wave

What is the relationship between relativity and the Doppler effect?



Expanding only certain variables inside a heredoc



2019 Community Moderator ElectionPassing directory from command line to shell scriptExpanding variables in zshCapturing data from a Fluke 1620a via Bash /dev/tcp file descriptorattempting to put dynamic input data in a variable via cat methodWhat is wrong with my init.d script [Segmentation fault]Variable not expanding inside another variable bashSet variable inside heredoc, use variable outside heredocPreform operation in bash only if a variable is less than a second variableparallel processing reading from a file in a loopCan the ability to overwrite a file with XML be exploited to execute code?Passing directory from command line to shell script










1















This is an extension of the question I asked .
Passing directory from command line to shell script



I have a script which writes another script using a heredoc. I need to be able to write unexpanded variables in the heredoc, so I use single quotes ('EOF'). However, I need one variable to be expanded. Given the script below, how can I write the value of $sourcedir inside the heredoc?



#!/bin/bash 

sourcedir="$1"
cd $sourcedir

find "$PWD" -maxdepth 2 -name *_R1*.fastq.gz > list1

fastq_list=$sourcedir/list1 echo `cat $fastq_list` num_files=$(wc -l <
$sourcedir/list1) echo $num_files



cat > run_array_job.sh<<'EOF'

#!/bin/bash -l
#$ -j y
#$ -cwd -S /bin/sh
#$ -l h_vmem=10G
#$ -pe smp 12

if [ -z "$SGE_TASK_ID" ]; then echo "Need to set SGE_TASK_ID" exit 1 fi


BASEDIR=$sourcedir

echo "BASEDIR" echo $BASEDIR

BASEFILES=$( ls *_R1.fastq.gz)
BASEFILES_ARRAY=($BASEFILES)
BASEFILE=$BASEFILES_ARRAY[($SGE_TASK_ID - 1)]
echo $BASEFILE


...................
...................

EOF

qsub -t 1-$num_files run_array_job.sh


I am running this script using



bash script.sh /home/dir/data


I am able to pass /home/dir/data as $1 to sourcedir but it also needs to be passed to BASEDIR , in array script which is submitted to cluster using qsub.










share|improve this question
























  • As simple as BASEDIR=$1. You need to escape all $'s in your embedded script. If you don't get what I mean I can write an answer.

    – Weijun Zhou
    Mar 12 at 19:05












  • @WeijunZhou the actual script is much, much longer than this (I know this from chatting with the OP), so escaping all $ just to keep the value of one variable will be complicated.

    – terdon
    Mar 12 at 19:08











  • @ron it would help if you could show how you want $sourcedir in the array script.

    – terdon
    Mar 12 at 19:08






  • 1





    In this case I usually do cat > wrapperscript.sh << EOF, then put run_array_job.sh $1 in the heredoc for wrapperscript.sh.

    – Weijun Zhou
    Mar 12 at 19:10






  • 1





    You can leave the EOF quoted so that you don't need to escape the $s for run_array_job.sh, but leave out the quote when you write heredoc for wrapperscript.sh

    – Weijun Zhou
    Mar 12 at 19:12















1















This is an extension of the question I asked .
Passing directory from command line to shell script



I have a script which writes another script using a heredoc. I need to be able to write unexpanded variables in the heredoc, so I use single quotes ('EOF'). However, I need one variable to be expanded. Given the script below, how can I write the value of $sourcedir inside the heredoc?



#!/bin/bash 

sourcedir="$1"
cd $sourcedir

find "$PWD" -maxdepth 2 -name *_R1*.fastq.gz > list1

fastq_list=$sourcedir/list1 echo `cat $fastq_list` num_files=$(wc -l <
$sourcedir/list1) echo $num_files



cat > run_array_job.sh<<'EOF'

#!/bin/bash -l
#$ -j y
#$ -cwd -S /bin/sh
#$ -l h_vmem=10G
#$ -pe smp 12

if [ -z "$SGE_TASK_ID" ]; then echo "Need to set SGE_TASK_ID" exit 1 fi


BASEDIR=$sourcedir

echo "BASEDIR" echo $BASEDIR

BASEFILES=$( ls *_R1.fastq.gz)
BASEFILES_ARRAY=($BASEFILES)
BASEFILE=$BASEFILES_ARRAY[($SGE_TASK_ID - 1)]
echo $BASEFILE


...................
...................

EOF

qsub -t 1-$num_files run_array_job.sh


I am running this script using



bash script.sh /home/dir/data


I am able to pass /home/dir/data as $1 to sourcedir but it also needs to be passed to BASEDIR , in array script which is submitted to cluster using qsub.










share|improve this question
























  • As simple as BASEDIR=$1. You need to escape all $'s in your embedded script. If you don't get what I mean I can write an answer.

    – Weijun Zhou
    Mar 12 at 19:05












  • @WeijunZhou the actual script is much, much longer than this (I know this from chatting with the OP), so escaping all $ just to keep the value of one variable will be complicated.

    – terdon
    Mar 12 at 19:08











  • @ron it would help if you could show how you want $sourcedir in the array script.

    – terdon
    Mar 12 at 19:08






  • 1





    In this case I usually do cat > wrapperscript.sh << EOF, then put run_array_job.sh $1 in the heredoc for wrapperscript.sh.

    – Weijun Zhou
    Mar 12 at 19:10






  • 1





    You can leave the EOF quoted so that you don't need to escape the $s for run_array_job.sh, but leave out the quote when you write heredoc for wrapperscript.sh

    – Weijun Zhou
    Mar 12 at 19:12













1












1








1








This is an extension of the question I asked .
Passing directory from command line to shell script



I have a script which writes another script using a heredoc. I need to be able to write unexpanded variables in the heredoc, so I use single quotes ('EOF'). However, I need one variable to be expanded. Given the script below, how can I write the value of $sourcedir inside the heredoc?



#!/bin/bash 

sourcedir="$1"
cd $sourcedir

find "$PWD" -maxdepth 2 -name *_R1*.fastq.gz > list1

fastq_list=$sourcedir/list1 echo `cat $fastq_list` num_files=$(wc -l <
$sourcedir/list1) echo $num_files



cat > run_array_job.sh<<'EOF'

#!/bin/bash -l
#$ -j y
#$ -cwd -S /bin/sh
#$ -l h_vmem=10G
#$ -pe smp 12

if [ -z "$SGE_TASK_ID" ]; then echo "Need to set SGE_TASK_ID" exit 1 fi


BASEDIR=$sourcedir

echo "BASEDIR" echo $BASEDIR

BASEFILES=$( ls *_R1.fastq.gz)
BASEFILES_ARRAY=($BASEFILES)
BASEFILE=$BASEFILES_ARRAY[($SGE_TASK_ID - 1)]
echo $BASEFILE


...................
...................

EOF

qsub -t 1-$num_files run_array_job.sh


I am running this script using



bash script.sh /home/dir/data


I am able to pass /home/dir/data as $1 to sourcedir but it also needs to be passed to BASEDIR , in array script which is submitted to cluster using qsub.










share|improve this question
















This is an extension of the question I asked .
Passing directory from command line to shell script



I have a script which writes another script using a heredoc. I need to be able to write unexpanded variables in the heredoc, so I use single quotes ('EOF'). However, I need one variable to be expanded. Given the script below, how can I write the value of $sourcedir inside the heredoc?



#!/bin/bash 

sourcedir="$1"
cd $sourcedir

find "$PWD" -maxdepth 2 -name *_R1*.fastq.gz > list1

fastq_list=$sourcedir/list1 echo `cat $fastq_list` num_files=$(wc -l <
$sourcedir/list1) echo $num_files



cat > run_array_job.sh<<'EOF'

#!/bin/bash -l
#$ -j y
#$ -cwd -S /bin/sh
#$ -l h_vmem=10G
#$ -pe smp 12

if [ -z "$SGE_TASK_ID" ]; then echo "Need to set SGE_TASK_ID" exit 1 fi


BASEDIR=$sourcedir

echo "BASEDIR" echo $BASEDIR

BASEFILES=$( ls *_R1.fastq.gz)
BASEFILES_ARRAY=($BASEFILES)
BASEFILE=$BASEFILES_ARRAY[($SGE_TASK_ID - 1)]
echo $BASEFILE


...................
...................

EOF

qsub -t 1-$num_files run_array_job.sh


I am running this script using



bash script.sh /home/dir/data


I am able to pass /home/dir/data as $1 to sourcedir but it also needs to be passed to BASEDIR , in array script which is submitted to cluster using qsub.







bash shell-script shell command-line cluster






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 12 at 19:09







Ron

















asked Mar 12 at 19:00









RonRon

4452613




4452613












  • As simple as BASEDIR=$1. You need to escape all $'s in your embedded script. If you don't get what I mean I can write an answer.

    – Weijun Zhou
    Mar 12 at 19:05












  • @WeijunZhou the actual script is much, much longer than this (I know this from chatting with the OP), so escaping all $ just to keep the value of one variable will be complicated.

    – terdon
    Mar 12 at 19:08











  • @ron it would help if you could show how you want $sourcedir in the array script.

    – terdon
    Mar 12 at 19:08






  • 1





    In this case I usually do cat > wrapperscript.sh << EOF, then put run_array_job.sh $1 in the heredoc for wrapperscript.sh.

    – Weijun Zhou
    Mar 12 at 19:10






  • 1





    You can leave the EOF quoted so that you don't need to escape the $s for run_array_job.sh, but leave out the quote when you write heredoc for wrapperscript.sh

    – Weijun Zhou
    Mar 12 at 19:12

















  • As simple as BASEDIR=$1. You need to escape all $'s in your embedded script. If you don't get what I mean I can write an answer.

    – Weijun Zhou
    Mar 12 at 19:05












  • @WeijunZhou the actual script is much, much longer than this (I know this from chatting with the OP), so escaping all $ just to keep the value of one variable will be complicated.

    – terdon
    Mar 12 at 19:08











  • @ron it would help if you could show how you want $sourcedir in the array script.

    – terdon
    Mar 12 at 19:08






  • 1





    In this case I usually do cat > wrapperscript.sh << EOF, then put run_array_job.sh $1 in the heredoc for wrapperscript.sh.

    – Weijun Zhou
    Mar 12 at 19:10






  • 1





    You can leave the EOF quoted so that you don't need to escape the $s for run_array_job.sh, but leave out the quote when you write heredoc for wrapperscript.sh

    – Weijun Zhou
    Mar 12 at 19:12
















As simple as BASEDIR=$1. You need to escape all $'s in your embedded script. If you don't get what I mean I can write an answer.

– Weijun Zhou
Mar 12 at 19:05






As simple as BASEDIR=$1. You need to escape all $'s in your embedded script. If you don't get what I mean I can write an answer.

– Weijun Zhou
Mar 12 at 19:05














@WeijunZhou the actual script is much, much longer than this (I know this from chatting with the OP), so escaping all $ just to keep the value of one variable will be complicated.

– terdon
Mar 12 at 19:08





@WeijunZhou the actual script is much, much longer than this (I know this from chatting with the OP), so escaping all $ just to keep the value of one variable will be complicated.

– terdon
Mar 12 at 19:08













@ron it would help if you could show how you want $sourcedir in the array script.

– terdon
Mar 12 at 19:08





@ron it would help if you could show how you want $sourcedir in the array script.

– terdon
Mar 12 at 19:08




1




1





In this case I usually do cat > wrapperscript.sh << EOF, then put run_array_job.sh $1 in the heredoc for wrapperscript.sh.

– Weijun Zhou
Mar 12 at 19:10





In this case I usually do cat > wrapperscript.sh << EOF, then put run_array_job.sh $1 in the heredoc for wrapperscript.sh.

– Weijun Zhou
Mar 12 at 19:10




1




1





You can leave the EOF quoted so that you don't need to escape the $s for run_array_job.sh, but leave out the quote when you write heredoc for wrapperscript.sh

– Weijun Zhou
Mar 12 at 19:12





You can leave the EOF quoted so that you don't need to escape the $s for run_array_job.sh, but leave out the quote when you write heredoc for wrapperscript.sh

– Weijun Zhou
Mar 12 at 19:12










2 Answers
2






active

oldest

votes


















2














You can most straightforwardly do this for your usage just by breaking your heredoc in two parts:



cat > run_array_job.sh<<'EOF'

#!/bin/bash -l
...
EOF

printf 'BASEDIR="%s"n" "$sourcedir" >> run_array_job.sh

cat >> run_array_job.sh<<'EOF'
echo "BASEDIR" echo $BASEDIR
...
EOF

qsub -t 1-$num_files run_array_job.sh


This just builds the first part of the file, appends the single line that you wanted the variable available for at the end of that first part using >>, and then joins the rest of the document on the end in the same way.



You end up with the same coherent file at the end, and only write a couple of lines extra. If you have multiple variables to pass through, you can put them all in at once as well.






share|improve this answer























  • Thanks @Michael ,@Weijun also provided the same answer in the chat room.

    – Ron
    Mar 12 at 20:53



















2














That's somewhat hard to do, since unlike with quotes, you can't just stop and restart expansion in an here-doc. But we could post-process the here-doc with sed:



#!/bin/bash
sourcedir=/some/path
sed -e "s,%%sourcedir%%,$sourcedir,g" << 'EOF'
some commands here with $variables not expanded
except for the special %%sourcedir%%, which is
EOF


Running that produces the output:



some commands here with $variables not expanded 
except for the special /some/path, which is


The sed command simply changes all instances of %%sourcedir%% with whatever the value of $sourcedir (as long as it doesn't contain commas; you'd need to change the separator for the s command to something else then.)



I changed the placeholder to another format for clarity's sake, but you could also leave it as $sourcedir and then use sed -e "s,$sourcedir,$sourcedir,". (Though note that it would also match $sourcedirectory and other similar variables, but not $sourcedir even though that would be equivalent in the shell.)



Alternatively, use GNU envsubst on the document, if you have it (it's part of gettext):



#!/bin/bash
export sourcedir=/some/path
envsubst '$sourcedir' << 'EOF'
some commands here with $variables not expanded
except for the special $sourcedir, which is
EOF





share|improve this answer

























  • Is envsubst GNU only?

    – Weijun Zhou
    Mar 12 at 19:49











  • @WeijunZhou, yep, seems to be.

    – ilkkachu
    Mar 12 at 20:16










Your Answer








StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f505949%2fexpanding-only-certain-variables-inside-a-heredoc%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














You can most straightforwardly do this for your usage just by breaking your heredoc in two parts:



cat > run_array_job.sh<<'EOF'

#!/bin/bash -l
...
EOF

printf 'BASEDIR="%s"n" "$sourcedir" >> run_array_job.sh

cat >> run_array_job.sh<<'EOF'
echo "BASEDIR" echo $BASEDIR
...
EOF

qsub -t 1-$num_files run_array_job.sh


This just builds the first part of the file, appends the single line that you wanted the variable available for at the end of that first part using >>, and then joins the rest of the document on the end in the same way.



You end up with the same coherent file at the end, and only write a couple of lines extra. If you have multiple variables to pass through, you can put them all in at once as well.






share|improve this answer























  • Thanks @Michael ,@Weijun also provided the same answer in the chat room.

    – Ron
    Mar 12 at 20:53
















2














You can most straightforwardly do this for your usage just by breaking your heredoc in two parts:



cat > run_array_job.sh<<'EOF'

#!/bin/bash -l
...
EOF

printf 'BASEDIR="%s"n" "$sourcedir" >> run_array_job.sh

cat >> run_array_job.sh<<'EOF'
echo "BASEDIR" echo $BASEDIR
...
EOF

qsub -t 1-$num_files run_array_job.sh


This just builds the first part of the file, appends the single line that you wanted the variable available for at the end of that first part using >>, and then joins the rest of the document on the end in the same way.



You end up with the same coherent file at the end, and only write a couple of lines extra. If you have multiple variables to pass through, you can put them all in at once as well.






share|improve this answer























  • Thanks @Michael ,@Weijun also provided the same answer in the chat room.

    – Ron
    Mar 12 at 20:53














2












2








2







You can most straightforwardly do this for your usage just by breaking your heredoc in two parts:



cat > run_array_job.sh<<'EOF'

#!/bin/bash -l
...
EOF

printf 'BASEDIR="%s"n" "$sourcedir" >> run_array_job.sh

cat >> run_array_job.sh<<'EOF'
echo "BASEDIR" echo $BASEDIR
...
EOF

qsub -t 1-$num_files run_array_job.sh


This just builds the first part of the file, appends the single line that you wanted the variable available for at the end of that first part using >>, and then joins the rest of the document on the end in the same way.



You end up with the same coherent file at the end, and only write a couple of lines extra. If you have multiple variables to pass through, you can put them all in at once as well.






share|improve this answer













You can most straightforwardly do this for your usage just by breaking your heredoc in two parts:



cat > run_array_job.sh<<'EOF'

#!/bin/bash -l
...
EOF

printf 'BASEDIR="%s"n" "$sourcedir" >> run_array_job.sh

cat >> run_array_job.sh<<'EOF'
echo "BASEDIR" echo $BASEDIR
...
EOF

qsub -t 1-$num_files run_array_job.sh


This just builds the first part of the file, appends the single line that you wanted the variable available for at the end of that first part using >>, and then joins the rest of the document on the end in the same way.



You end up with the same coherent file at the end, and only write a couple of lines extra. If you have multiple variables to pass through, you can put them all in at once as well.







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 12 at 20:52









Michael HomerMichael Homer

49.9k8135175




49.9k8135175












  • Thanks @Michael ,@Weijun also provided the same answer in the chat room.

    – Ron
    Mar 12 at 20:53


















  • Thanks @Michael ,@Weijun also provided the same answer in the chat room.

    – Ron
    Mar 12 at 20:53

















Thanks @Michael ,@Weijun also provided the same answer in the chat room.

– Ron
Mar 12 at 20:53






Thanks @Michael ,@Weijun also provided the same answer in the chat room.

– Ron
Mar 12 at 20:53














2














That's somewhat hard to do, since unlike with quotes, you can't just stop and restart expansion in an here-doc. But we could post-process the here-doc with sed:



#!/bin/bash
sourcedir=/some/path
sed -e "s,%%sourcedir%%,$sourcedir,g" << 'EOF'
some commands here with $variables not expanded
except for the special %%sourcedir%%, which is
EOF


Running that produces the output:



some commands here with $variables not expanded 
except for the special /some/path, which is


The sed command simply changes all instances of %%sourcedir%% with whatever the value of $sourcedir (as long as it doesn't contain commas; you'd need to change the separator for the s command to something else then.)



I changed the placeholder to another format for clarity's sake, but you could also leave it as $sourcedir and then use sed -e "s,$sourcedir,$sourcedir,". (Though note that it would also match $sourcedirectory and other similar variables, but not $sourcedir even though that would be equivalent in the shell.)



Alternatively, use GNU envsubst on the document, if you have it (it's part of gettext):



#!/bin/bash
export sourcedir=/some/path
envsubst '$sourcedir' << 'EOF'
some commands here with $variables not expanded
except for the special $sourcedir, which is
EOF





share|improve this answer

























  • Is envsubst GNU only?

    – Weijun Zhou
    Mar 12 at 19:49











  • @WeijunZhou, yep, seems to be.

    – ilkkachu
    Mar 12 at 20:16















2














That's somewhat hard to do, since unlike with quotes, you can't just stop and restart expansion in an here-doc. But we could post-process the here-doc with sed:



#!/bin/bash
sourcedir=/some/path
sed -e "s,%%sourcedir%%,$sourcedir,g" << 'EOF'
some commands here with $variables not expanded
except for the special %%sourcedir%%, which is
EOF


Running that produces the output:



some commands here with $variables not expanded 
except for the special /some/path, which is


The sed command simply changes all instances of %%sourcedir%% with whatever the value of $sourcedir (as long as it doesn't contain commas; you'd need to change the separator for the s command to something else then.)



I changed the placeholder to another format for clarity's sake, but you could also leave it as $sourcedir and then use sed -e "s,$sourcedir,$sourcedir,". (Though note that it would also match $sourcedirectory and other similar variables, but not $sourcedir even though that would be equivalent in the shell.)



Alternatively, use GNU envsubst on the document, if you have it (it's part of gettext):



#!/bin/bash
export sourcedir=/some/path
envsubst '$sourcedir' << 'EOF'
some commands here with $variables not expanded
except for the special $sourcedir, which is
EOF





share|improve this answer

























  • Is envsubst GNU only?

    – Weijun Zhou
    Mar 12 at 19:49











  • @WeijunZhou, yep, seems to be.

    – ilkkachu
    Mar 12 at 20:16













2












2








2







That's somewhat hard to do, since unlike with quotes, you can't just stop and restart expansion in an here-doc. But we could post-process the here-doc with sed:



#!/bin/bash
sourcedir=/some/path
sed -e "s,%%sourcedir%%,$sourcedir,g" << 'EOF'
some commands here with $variables not expanded
except for the special %%sourcedir%%, which is
EOF


Running that produces the output:



some commands here with $variables not expanded 
except for the special /some/path, which is


The sed command simply changes all instances of %%sourcedir%% with whatever the value of $sourcedir (as long as it doesn't contain commas; you'd need to change the separator for the s command to something else then.)



I changed the placeholder to another format for clarity's sake, but you could also leave it as $sourcedir and then use sed -e "s,$sourcedir,$sourcedir,". (Though note that it would also match $sourcedirectory and other similar variables, but not $sourcedir even though that would be equivalent in the shell.)



Alternatively, use GNU envsubst on the document, if you have it (it's part of gettext):



#!/bin/bash
export sourcedir=/some/path
envsubst '$sourcedir' << 'EOF'
some commands here with $variables not expanded
except for the special $sourcedir, which is
EOF





share|improve this answer















That's somewhat hard to do, since unlike with quotes, you can't just stop and restart expansion in an here-doc. But we could post-process the here-doc with sed:



#!/bin/bash
sourcedir=/some/path
sed -e "s,%%sourcedir%%,$sourcedir,g" << 'EOF'
some commands here with $variables not expanded
except for the special %%sourcedir%%, which is
EOF


Running that produces the output:



some commands here with $variables not expanded 
except for the special /some/path, which is


The sed command simply changes all instances of %%sourcedir%% with whatever the value of $sourcedir (as long as it doesn't contain commas; you'd need to change the separator for the s command to something else then.)



I changed the placeholder to another format for clarity's sake, but you could also leave it as $sourcedir and then use sed -e "s,$sourcedir,$sourcedir,". (Though note that it would also match $sourcedirectory and other similar variables, but not $sourcedir even though that would be equivalent in the shell.)



Alternatively, use GNU envsubst on the document, if you have it (it's part of gettext):



#!/bin/bash
export sourcedir=/some/path
envsubst '$sourcedir' << 'EOF'
some commands here with $variables not expanded
except for the special $sourcedir, which is
EOF






share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 12 at 20:55

























answered Mar 12 at 19:38









ilkkachuilkkachu

61.5k10100177




61.5k10100177












  • Is envsubst GNU only?

    – Weijun Zhou
    Mar 12 at 19:49











  • @WeijunZhou, yep, seems to be.

    – ilkkachu
    Mar 12 at 20:16

















  • Is envsubst GNU only?

    – Weijun Zhou
    Mar 12 at 19:49











  • @WeijunZhou, yep, seems to be.

    – ilkkachu
    Mar 12 at 20:16
















Is envsubst GNU only?

– Weijun Zhou
Mar 12 at 19:49





Is envsubst GNU only?

– Weijun Zhou
Mar 12 at 19:49













@WeijunZhou, yep, seems to be.

– ilkkachu
Mar 12 at 20:16





@WeijunZhou, yep, seems to be.

– ilkkachu
Mar 12 at 20:16

















draft saved

draft discarded
















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f505949%2fexpanding-only-certain-variables-inside-a-heredoc%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







-bash, cluster, command-line, shell, shell-script

Popular posts from this blog

Frič See also Navigation menuinternal link

Identify plant with long narrow paired leaves and reddish stems Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?What is this plant with long sharp leaves? Is it a weed?What is this 3ft high, stalky plant, with mid sized narrow leaves?What is this young shrub with opposite ovate, crenate leaves and reddish stems?What is this plant with large broad serrated leaves?Identify this upright branching weed with long leaves and reddish stemsPlease help me identify this bulbous plant with long, broad leaves and white flowersWhat is this small annual with narrow gray/green leaves and rust colored daisy-type flowers?What is this chilli plant?Does anyone know what type of chilli plant this is?Help identify this plant

fontconfig warning: “/etc/fonts/fonts.conf”, line 100: unknown “element blank” The 2019 Stack Overflow Developer Survey Results Are In“tar: unrecognized option --warning” during 'apt-get install'How to fix Fontconfig errorHow do I figure out which font file is chosen for a system generic font alias?Why are some apt-get-installed fonts being ignored by fc-list, xfontsel, etc?Reload settings in /etc/fonts/conf.dTaking 30 seconds longer to boot after upgrade from jessie to stretchHow to match multiple font names with a single <match> element?Adding a custom font to fontconfigRemoving fonts from fontconfig <match> resultsBroken fonts after upgrading Firefox ESR to latest Firefox