I have found many snippets here and in other places that answer parts of this question. I have even managed to do this in many steps in an inefficient manner. If it is possible, I would really like to find single lines of execution that will perform this task, rather than having to assign to a variable and copy it a few times to perform the task.
e.g.
executeToVar ()
{
# Takes Arg1: NAME OF VARIABLE TO STORE IN
# All Remaining Arguments Are Executed
local STORE_INvar="${1}" ; shift
eval ${STORE_INvar}=\""$( "$@" 2>&1 )"\"
}
Overall does work, i.e. $ executeToVar SOME_VAR ls -l * #
will actually fill SOME_VAR
with the output of the execution of the ls -l *
command that is taken from the rest of the arguments. However, if the command was to output empty lines at the end, (for e.g. - echo -e -n '\n\n123\n456\n789\n\n'
which should have 2 x new lines at the start and the end ) these are stripped by bash's sub-execution process. I have seen in other posts similar to this that this has been solved by adding a token 'x' to the end of the stream, e.g. turning the sub-execution into something like:
eval ${STORE_INvar}=\""$( "$@" 2>&1 ; echo -n x )"\" # <-- ( Add echo -n x )
# and then if it wasn't an indirect reference to a var:
STORE_INvar=${STORE_INvar%x}
# However no matter how much I play with:
eval "${STORE_INvar}"=\""${STORE_INvar%x}"\"
# I am unable to indirectly remove the x from the end.
Anyway, I also need 2 x other variants on this, one that assigns the STDIN stream
to the var and one that assigns the contents of a file to the var which I assume will be variations of this involving $( cat ${1} )
, or maybe $( cat ${1:--} )
to give me a '-' if no filename. But, none of that will work until I can sort out the removal of the x that is needed to ensure accurate assignment of multi line variables.
I have also tried (but to no avail):
IFS='' read -d '' "${STORE_INvar}" <<<"$( $@ ; echo -n x )"
eval \"'${STORE_INvar}=${!STORE_INvar%x}'\"
what'w wrong with storing in a file:
where "stuffToFile" tests for a. > 1 argument, b. input on a pipe
and
where "stoffToFile" is a function:
so, if "stuff" has leading and trailing blank lines, then you must:
This is close to optimal -- but drop the
eval
.The one problem this formulation still has is that
$()
strips trailing newlines. If you want to prevent that, you need to add your own trailing character inside the subshell, and strip it off yourself.If you want to read all content from stdin into a variable, this is particularly easy:
...used as:
...or...
Testing these:
...and...