Skip to main content
added 81 characters in body
Source Link
Stéphane Chazelas
  • 584.7k
  • 96
  • 1.1k
  • 1.7k

It you pass an argument like $USER$PATH to envsubst, then it expands only those variables that are referenced in that argument.

So one way could be to pass it all the currently defined environment variables in that format. With zsh:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters is a special associative array that maps variable names to their type
  • $parameters[(R)*export*] expands to all the elements of the associative array whose value contains export.
  • with the k parameter expansion flag, the key instead of the value is returned
  • j:$: joins those elements with $ in between, and we add one at the start.

With other shells, you can always revert to perl to get that list:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"

ThoughBeware both disclose your environment variable names in the output of ps.

Instead, you could also do the whole thing in perl:

perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'

Beware it has the same limitations as envsubst in that it won't expand things like ${VAR:-x} and would expand $HOME in things like \$HOME or $$HOME which a shell wouldn't.

It you pass an argument like $USER$PATH to envsubst, then it expands only those variables that are referenced in that argument.

So one way could be to pass it all the currently defined environment variables in that format. With zsh:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters is a special associative array that maps variable names to their type
  • $parameters[(R)*export*] expands to all the elements of the associative array whose value contains export.
  • with the k parameter expansion flag, the key instead of the value is returned
  • j:$: joins those elements with $ in between, and we add one at the start.

With other shells, you can always revert to perl to get that list:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"

Though you could also do the whole thing in perl:

perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'

Beware it has the same limitations as envsubst in that it won't expand things like ${VAR:-x} and would expand $HOME in things like \$HOME or $$HOME which a shell wouldn't.

It you pass an argument like $USER$PATH to envsubst, then it expands only those variables that are referenced in that argument.

So one way could be to pass it all the currently defined environment variables in that format. With zsh:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters is a special associative array that maps variable names to their type
  • $parameters[(R)*export*] expands to all the elements of the associative array whose value contains export.
  • with the k parameter expansion flag, the key instead of the value is returned
  • j:$: joins those elements with $ in between, and we add one at the start.

With other shells, you can always revert to perl to get that list:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"

Beware both disclose your environment variable names in the output of ps.

Instead, you could also do the whole thing in perl:

perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'

Beware it has the same limitations as envsubst in that it won't expand things like ${VAR:-x} and would expand $HOME in things like \$HOME or $$HOME which a shell wouldn't.

added 398 characters in body
Source Link
Stéphane Chazelas
  • 584.7k
  • 96
  • 1.1k
  • 1.7k

It you pass an argument like $USER$PATH to envsubst, then it expands only those variables that are referenced in that argument.

So one way could be to pass it all the currently defined environment variables in that format. With zsh:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters is a special associative array that maps variable names to their type
  • $parameters[(R)*export*] expands to all the elements of the associative array whose value contains export.
  • with the k parameter expansion flag, the key instead of the value is returned
  • j:$: joins those elements with $ in between, and we add one at the start.

With other shells, you can always revert to perl to get that list:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"

Though you could also do the whole thing in perl:

perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'

Beware it has the same limitations as envsubst in that it won't expand things like ${VAR:-x} and would expand $HOME in things like \$HOME or $$HOME which a shell wouldn't.

It you pass an argument like $USER$PATH to envsubst, then it expands only those variables that are referenced in that argument.

So one way could be to pass it all the currently defined environment variables in that format. With zsh:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters is a special associative array that maps variable names to their type
  • $parameters[(R)*export*] expands to all the elements of the associative array whose value contains export.
  • with the k parameter expansion flag, the key instead of the value is returned
  • j:$: joins those elements with $ in between, and we add one at the start.

With other shells, you can always revert to perl to get that list:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"

It you pass an argument like $USER$PATH to envsubst, then it expands only those variables that are referenced in that argument.

So one way could be to pass it all the currently defined environment variables in that format. With zsh:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters is a special associative array that maps variable names to their type
  • $parameters[(R)*export*] expands to all the elements of the associative array whose value contains export.
  • with the k parameter expansion flag, the key instead of the value is returned
  • j:$: joins those elements with $ in between, and we add one at the start.

With other shells, you can always revert to perl to get that list:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"

Though you could also do the whole thing in perl:

perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'

Beware it has the same limitations as envsubst in that it won't expand things like ${VAR:-x} and would expand $HOME in things like \$HOME or $$HOME which a shell wouldn't.

added 59 characters in body
Source Link
Stéphane Chazelas
  • 584.7k
  • 96
  • 1.1k
  • 1.7k

It you pass an argument like $USER$PATH to envsubst, then it expands only those variables that are referenced in that argument.

So one way could be to pass it all the currently defined environment variables in that format. With zsh:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters is a special associative array that maps variable names to theytheir type
  • $parameters[(R)*export*] expands to all the elements of the associateassociative array whose value contains export.
  • with the k parameter expansion flag, the key instead of the value is returned
  • j:$: joins those elements with $ in between, and we add one at the start.

With other shells, you can always revert to perl to get that list:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"

It you pass an argument like $USER$PATH to envsubst, then it expands only those variables that are referenced in that argument.

So one way could be to pass it all the currently defined environment variables in that format. With zsh:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters is a special associative array that maps variable names to they type
  • $parameters[(R)*export*] expands to all the elements of the associate array whose value contains export.
  • with the k parameter expansion flag, the key instead of the value is returned
  • j:$: joins those elements with $ in between, and we add one at the start.

With other shells, you can always revert to perl to get that list:

envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"

It you pass an argument like $USER$PATH to envsubst, then it expands only those variables that are referenced in that argument.

So one way could be to pass it all the currently defined environment variables in that format. With zsh:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
  • $parameters is a special associative array that maps variable names to their type
  • $parameters[(R)*export*] expands to all the elements of the associative array whose value contains export.
  • with the k parameter expansion flag, the key instead of the value is returned
  • j:$: joins those elements with $ in between, and we add one at the start.

With other shells, you can always revert to perl to get that list:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"
Source Link
Stéphane Chazelas
  • 584.7k
  • 96
  • 1.1k
  • 1.7k
Loading