Advertisement

Variable expansion in a "here" file

Started by April 01, 2008 11:06 AM
4 comments, last by Bregma 16 years, 7 months ago
I'm using a here file which includes a variable defined in the script which does expand as expected when the code for the here file is inline in the script. When I cut the code out of the script and paste it into its own file to be used as the here file, the variable does not expand. Since I only use the one variable and it happens to be in the last line of the here file, my current workaround is to still use the separate file but leave this last line out of it, and in the script use the syntax for an inline here file consisting of two lines: `cat herefile` dosomethingwith $MYVAR Is there any way to make this work with that last line inside the external herefile? I realize that catting a here file is not how it's designed to work, but as far as my workaround goes, if I used the external here file as designed (redirect the contents of the file as input to the program using the here file), I wouldn't be able to include my last line - the here file input would end at the end of the external file.
Err, I'm sure I doesn't understand your question totally ;) Do you mean that the definition of a variable in one script file B isn't visible in another script file A although B is executed by A? That behaviour would be correct, since executing a shell script is done in an own shell with its own environment. That is like using the "exec" command (it is named "exec" at least by the bash). One can avoid using an own shell by not executing but "sourcing" B inside A. For the bash, the syntax would be "source B". Then B would use the same environment as A does, and any variable defined in B would be shared with A.

Is that what you're asking for?
Advertisement
No, a "here" file is not a script, it's a way of sending automated input to an interactive program within a script. This input can either be within the script itself or read from another file. When it's in the script, the value of my variable is used, which is what I want as far as my variable is concerned. When it is read from a file, which is the method I would prefer to use, the name of my variable is used.
When you switch the input data from a here document to an external diskfile it's not longer a here document

Here's what you need to do.

(1) Replace the variable, say $MYVAR, with a substitution token in your data file. For instance, "@@MYVAR@@".

(2) Run you data file through a substitution filter like, for instance, sed.

Instead of this,
  fudge <-EOF    This is a here document.    It's got a variable $MYVAL    EOF
you would instead do this.
  sed -e "s,@@MYVAR@@,$MYVAR," mydatafile | fudge
Where "fudge" is your program previously consuming your herefile. This moves the variable substitution from the here document into the sed command line.

Bingo.

--smw

Stephen M. Webb
Professional Free Software Developer

Quote: Original post by Bregma
When you switch the input data from a here document to an external diskfile it's not longer a here document

Could here documents be any more misleadingly named? The name implies a stand-alone external file, but when you actually do this it is no longer technically a here file/document? It's only a true here file when it exists as one portion of a larger file? Bah. What do you call this, then, inside a script?

ftp someserver.com <herefile

Simply input redirection?

Quote:
Here's what you need to do.

(1) Replace the variable, say $MYVAR, with a substitution token in your data file. For instance, "@@MYVAR@@".

(2) Run you data file through a substitution filter like, for instance, sed.

Instead of this,
  fudge <-EOF    This is a here document.    It's got a variable $MYVAL    EOF
you would instead do this.
  sed -e "s,@@MYVAR@@,$MYVAR," mydatafile | fudge
Where "fudge" is your program previously consuming your herefile. This moves the variable substitution from the here document into the sed command line.

Bingo.

--smw

Thanks, I can't try it right now, but I'll keep this in mind. Again, I can't test it now, but I'm wondering if I could add my problematic variable-containing line to the external file and replace my `cat herefile` with `eval cat herefile`. Just as an exercise, though, I'm curious if there is a way to get the variable expanded using an external file as a here file or input redirection or whatever it's called.

Quote: Original post by BerwynIrish
What do you call this, then, inside a script?

ftp someserver.com <herefile

Simply input redirection?

Yep.
Quote: I'm wondering if I could add my problematic variable-containing line to the external file and replace my `cat herefile` with `eval cat herefile`.

Nope. There are at least two ways you could interpret and execute the contents of an external file as a shell script, but that's not what you're trying to do any ways. You're trying to substitute variables in a data file. That's what sed is for. Of course, you could go hog-wild and use a bigger hammer like awk or PERL or write a C program to do that (and don't laugh, I work with people who would do that), but why not just use the tool designed to do what you're trying to do?
Quote: Just as an exercise, though, I'm curious if there is a way to get the variable expanded using an external file as a here file or input redirection or whatever it's called.

No. If you need to filter the input you need to insert a filter into the pipeline. That how Unix was designed. It's very efficient to do it that way and it's the Unix idiom.

If it's really important to you to use a here document, you could do something like this.
  fudge <-EOF    $(sed -s "s/@@MYVAR@@/$MYVAR/g" mydatafile)  EOF
But, um, are your trying to fool your friends and confuse your enemies?

--smw

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement