When you run eval 'echo "1" > ~/Desktop/in/foo'
, the shell removes the single-quotes, then eval
evaluates echo "1" > ~/Desktop/in/foo
.
When you run eval "$_cmd"
(in your pre-update code), the shell expands $_cmd
and removes the double quotes, then eval
evaluates 'echo "1" > ~/Desktop/in/foo'
. Note the single quotes. You don't want eval
to see them, remove them from the here document.
In your updated code you probably want eval
to evaluate echo "1" > ~/Desktop/in/'foo (bis)'
, so use this exact line in the here document.
Well, "exact" is not the right word in general. In general << EOF
(as opposed to e.g. << 'EOF'
) expands variables and few other things in the here document (there are none in your example, but in general this is how it works). Then IFS= read _cmd
is not IFS= read -r _cmd
. Finally eval
gets a string which is not necessarily the exact string you used.
Evaluating line by line makes evaluating multi-line commands impossible.
Unless you really want to rely on what << EOF
and IFS= read
do to the string(s) you provide (and you know what you're doing), just write the code directly in the script. After all, you want the shell interpreting the script to evaluate echo "1" > ~/Desktop/in/foo
. It's not even you want some other shell process. There is no need for a here document here.
I guess preprocessing code for another shell process may make sense (in some cases and when you're careful), but then you should use e.g. bash << EOF
, not read
.
Another thing: the snippet done < <(cat << EOF
can be simplified to done << EOF
(note this change requires removing the )
from the end of your code).
bash < <(cat << EOF...
instead ofbash << EOF
, right? (the latter yieldsbash: syntax error near unexpected token
)'`) – Erwann Mar 19 '22 at 06:43bash << EOF
. There is no(
in it. I think your contraption withcat
works because it provides(
matching the)
you had. My guess is you did not remove this)
when usingbash << EOF
, hence the error. The real fix is in removing the)
, not in voodoo withcat
. – Kamil Maciorowski Mar 19 '22 at 06:55{
, Enter, then (possibly multi-line) code, place sole}
in the last line; hit Enter. Or (in Bash) Ctrl+x, Ctrl+e, type the code, save and exit the editor (interesting variant here, other shells may provide similar functionality). Next time do not fall into XY problem. – Kamil Maciorowski Mar 20 '22 at 07:59