Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

Working on some bash functions, I didn't know source ... command, so I used eval $(cat ...) instead. Now I am wondering, whethe should I change every use of that, or is it just the same function?

They appear to work the same now, but maybe there will be some misleading differences later, I just want to know.

share|improve this question
add comment

3 Answers

up vote 2 down vote accepted

eval $(cat ...) doesn't work in all cases. For example line breaks are converted to a single space by $(cat ...) before the content is processed by eval. This often breaks multi line statements like loops and here documents.

Try for example the following file with both methods:

for i in 1 2 3; do
 echo $i
done

cat<<EOF
a
b
c
EOF
share|improve this answer
2  
If you use quotes, the whitespace will stay intact: eval "$(cat file)" –  glenn jackman Aug 11 '12 at 21:39
    
Yes, that should work, too. But if one has to change the code anyway I's prefer source as it is a command made for specifically this. –  Florian Diesch Aug 12 '12 at 4:12
add comment

As already mentioned by @glennjackman, you'll want to quote the command substitution, else word splitting and pathname expansion will modify the content before it gets evaled. And while both will execute the commands from the file, there are differences.

  • When you source a script, various special shell variables will be modified, mainly the BASH_SOURCE, BASH_LINENO and FUNCNAME arrays. These are useful for printing error messages and debugging.

  • You can return from a sourced script with the return command (help return). With the eval, you won't get that effect. And similarly a RETURN trap will not be triggered for the eval.

  • When sourcing a script, you can pass arguments to it. You can't do that with that eval.

  • With the eval, the command substitution will read the entire content of the file into memory before passing it on to eval. When you source it, bash will read from the file as it goes.

share|improve this answer
add comment

There's a nice summary of what source, eval and exec do here: http://www.unix.com/shell-programming-scripting/54347-bash-shell-exec-eval-source-looking-help-understand.html

I'd think your use of eval and source'ing the file will do the same thing. I'm not completely sure, though, that variables inside the subscript will behave the same in any case. I'd recommend using source if possible, because it's the more straightforward way to go and makes your code more readable.

share|improve this answer
    
comletely tangential: bash has a shorthand for $(cat file) -> $(< file) –  glenn jackman Aug 11 '12 at 21:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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