[…] the remaining terms (nnnn >~/...
) seem to get lumped together as if they were a single parameter, […]
Not exactly. The line actually gets split on whitespace (or whatever $IFS
specifies), but the problem is that the redirection operator >
cannot be taken from a shell variable. For example, this snippet:
gt='>'
echo $gt foo.txt
will print > foo.txt
, rather than printing a newline to foo.txt
.
And you'll have similar problems with various other shell metacharacters, such as quotation marks.
What you need is the eval
builtin, which takes a string, parses it as a shell command, and runs it:
pbpaste | egrep -o [^$]+ | while IFS= read -r LINE; do eval "$LINE"; done
(The IFS=
and -r
and the double-quotes around $LINE
are all to prevent any other processing besides the processing performed by eval
, so that e.g. whitespace inside quotation marks will be preserved.)
Another possibility, depending on the details of what you need, is simply to pipe the commands into a new instance of Bash:
pbpaste | egrep -o [^$]+ | bash
Edited to add: For that matter, it occurs to me that you can pass everything to eval
in a single batch; just as you can (per your comment) write pbpaste | bash
, you can also write eval "$(pbpaste)"
. That will support multiline while
-loops and so on, while still running in the current shell (useful if you want it to be able to reference shell parameters, to set environment variables, etc., etc.).