Maybe this is obvious to all the linux and bash-fu experts out there, but I just discovered it, thought it was pretty cool and worth sharing for anyone else who isn't quite a bash expert.
Ok, so bash has a feature which takes the output of a command and runs it (no, this isn't the part that's new to me ;), I'll get to that part in a bit). Let's use the print working directory command as an example:
$ cd ~ $ pwd /home/my-user-name
Now let's get a command that just simply outputs the command we want:
$ echo pwd pwd
And then bash's basic feature to execute that result (two different ways to do it):
$ `echo pwd` /home/my-user-name $ eval $(echo pwd) /home/my-user-name
Alright, neat, but basic stuff.
Unfortunately, that trick only works when you're evaluating a single line. Try to evaluate multiple lines and it won't work. (The newlines get converted to spaces and it all gets interpreted as one command.)
To demonstrate, let's make a basic script:
$ touch display-a-command $ my-favorite-editor display-a-command
Copy-paste, save and exit:
#!/bin/bash echo pwd echo pwd
$ chmod +x display-a-command $ ./display-a-command pwd pwd
Ok. So we have a basic command that outputs two lines of commands. Try to evaluate (You get the same result using either eval method):
$ `./display-a-command` /home/my-user-name
Fucknuggets. It only ran "pwd" once. The two lines got mashed together into one line and bash really executed the single command pwd pwd. The second "pwd" was ignored as an unused argument to the first "pwd". That's not at all what we wanted.
The Cool Part
Turns out there's an easy way to do a multi-line eval:
$ eval "`./display-a-command`" /home/my-user-name /home/my-user-name
Yup. That's it. The internal `./display-a-command` evaluates to our two-line command, and the double-quotes ensure the newline gets preserved when passed to eval.
It even works when display-a-command's output includes backticks and quotes:
$ cat display-a-command2 #!/bin/bash echo \`echo pwd\` echo eval \"pwd\" $ chmod +x display-a-command2 $ ./display-a-command2 `echo pwd` eval "pwd" $ eval "`./display-a-command2`" /home/my-user-name /home/my-user-name
Nice. Cool, huh? At least I think it is, anyway.