I've looked this up and can't find an answer, I apologise in advance if it's been previously asked.
I'm using shell on FreeBSD (/bin/sh
) and I want to dump to stdout all shell (not environment) variables starting with _myvar_
. The closest I can get is set | grep '^_myvar_'
but that only dumps the first line of multiline variables (some will be multiline and I need them in full), and it could be error prone in pathological edge cases such as a string containing "myvar" that happens to line-break just before that part.
if I could list just variable names (not values), then I could filter within a do...read...while
and get the values one at a time just for vars with matching names, but I can't find a way to do this. I also can't filter the full output, because there is no deterministic way to tell whether an output line contains a continuation or a new variable, that doesn't have edge-case issues with strings containing _myvar_
, =
or newline (\n)
characters, or possibly, trailing spaces. I don't want to modify the environment, because the code is included in other code and the environment has to be stable for it.
It isn't a problem for the output/list to include any matching environment variables if that helps (if any exist – it's extremely unlikely they will)
Is there a way to do this?
Best Answer
As the
set
builtin of FreeBSDsh
outputs in a format that is suitable for reinput to the shell, you can do:That is prefix each line of the output of
set
with"out "
and have that evaluated as shell code (whereout
is a function that prints the substring of its first argument up to the first=
).sed
would also insert"out "
in the content of multiline variable, but that would still be included in the argument that ourout
function receives and past the first=
, so in the part we're not displaying.For instance, on a
set
output like:We would be evaluating:
But that's still fine as
out
is only called 3 times for those 3 variables.To print both variable name and value:
Note that it only outputs variables, not other types of parameters like
$-
, positional parameters...That approach only works for
sh
implementations whereset
only outputs scalar variables (won't work for arrays or associative arrays or compound variables, whereout var=(x)
becomes a syntax error). Those shells that have other variable types often also have better introspection features.In
zsh
:or for the names only
In
bash
: