0

I want to create a file from a bash script. But I need to expand some variables and print others literally is this possible?

cat <<EOF >  file.sh
$EXPAND
$PRINTLITERALLY
EOF

Also I'm trying to create a very big file, when I try to paste it in my terminal to test I get errors like:

-bash: urlencode: command not found

So it seems I may have stuff there that the bash is interpreting, will that affect my bash script when running it? I feel like there must be a better way to create files from my bash scripts

5
EXPAND=value
cat <<EOF >  file.sh
$EXPAND
\$PRINTLITERALLY
EOF

would create file.sh with

value
$PRINTLITERALLY

as contents.

(you'd need to add a backslash before each occurrence of $ or ` where you don't want the corresponding parameter expansion, arithmetic expansion or command substitution to be expanded. And you'd also need to escape some backslash characters as well).

Another approach:

cat - << EXPANDED /dev/fd/3 3<< 'NOT-EXPANDED' /dev/fd/4 4<< EXPANDED-AGAIN > file.sh
$EXPAND
`echo test`
...
EXPANDED
$PRINTLITERALLY
`echo test`
...
NOT-EXPANDED
$EXPAND
...
EXPANDED-AGAIN

The here documents where the delimiter is quoted (as in 3<< 'NOT-EXPANDED' above) don't undergo shell expansions, so you can decide of sections where expansions are performed and some where they're not.

With the above, you'd get:

value
test
...
$PRINTLITERALLY
`echo test`
...
value
...

If you wanted to expand just one specific set of variables wherever they appear leaving all the other parameter expansions, command substitutions, arithmetic expansions unexpanded, you could use the envsubst utility shipped with GNU gettext.

Note however that it only expands $var and ${var}, not any other form of parameter expansion involving the $var variable (like ${var#?}, ${var[x]}...)

EXPAND=value EXPAND_AS_WELL=othervalue
export EXPAND EXPAND_AS_WELL
envsubst '$EXPAND$EXPAND_AS_WELL' << '__end_of_envsubst__' > file.sh
$EXPAND ${EXPAND} ${EXPAND#?} ${EXPAND[0]} $EXPAND[0] $EXPANDÉ \$EXPAND
$PRINTLITERALLY $EXPAND_AS_WELL
`echo test`
__end_of_envsubst__

gives:

value value ${EXPAND#?} ${EXPAND[0]} value[0] valueÉ \value
$PRINTLITERALLY othervalue
`echo test`

See info gettext envsubst for further details.

| improve this answer | |
  • Thanks. How do you handle stuff in the text that might be interpreted by the shell? It's a big and somewhat complex script... if there is a way to do the inverse it would be easier too...expand 1 variable only, rest print literally – Freedo Jan 6 at 8:51
  • I still can't create a correct file. Bash is executing and interpreting stuff inside my bash script. I'm using a bash script to write another bash script. Which has commands like $(command), functions... example () {commands}, variables, etc... must be there a easier and fastest way to create a file like that – Freedo Jan 6 at 10:21
  • @Freedo, see edit. – Stéphane Chazelas Jan 6 at 10:32
  • Thanks! That kept my terminal quiet :) what if you want to add another variable to envsubst? I need $user and $password – Freedo Jan 6 at 10:46
  • @Freedo, see edit – Stéphane Chazelas Jan 6 at 10:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.