14

I use Bash 4.3.48(1) and I have a .sh file containing about 20 variables right under the shebang. The file contains only variables.

This is the pattern:

x="1"
y="2"
...

I need to export all these variables in a DRY way: For example, one export to all vars, instead say 20 export for 20 vars.

What's the most elegant way (shortest, most efficient by all means) to do that inside that file?

A for loop? An array? maybe something simpler than these (some kind of collection sugar syntax)?

2 Answers2

26

Use set -a (or the equivalent set -o allexport) at the top of your file to enable the allexport shell option. Then use set +a (or set +o allexport) at the end of the file (wherever appropriate) to disable the allexport shell option.

Using enabling the allexport shell option will have the following effect (from the bash manual):

Each variable or function that is created or modified is given the export attribute and marked for export to the environment of subsequent commands.

This shell option, set with either set -a orset -o allexport, is defined in POSIX (and should therefore be available in all sh-like shells) as

When this option is on, the export attribute shall be set for each variable to which an assignment is performed; [...] If the assignment precedes a utility name in a command, the export attribute shall not persist in the current execution environment after the utility completes, with the exception that preceding one of the special built-in utilities causes the export attribute to persist after the built-in has completed. If the assignment does not precede a utility name in the command, or if the assignment is a result of the operation of the getopts or read utilities, the export attribute shall persist until the variable is unset.

The variables set while this option is enabled will be exported, i.e. made into environment variables. These environment variables will be available to the current shell environment and to any subsequently created child process environments, as per usual.

This means that you will have to either

  • source this file (using ., or source in shells that have this command), or
  • start the processes that should have access to the variables from this file.
Kusalananda
  • 333,661
4

Here's a hack:

source <(sed 's/^/export /' file.sh)

I assume your shell is like bash and supports process substitutions

Or, edit the file itself:

sed -i 's/[^=]\+/export &; &/' file.sh
glenn jackman
  • 85,964
  • I guess you can also use $0 when doing it from the same file (in the end of the file, under all variable declarations). – Arcticooling Feb 11 '18 at 02:35
  • @user9303970 If you mean putting the sed command that changes file.sh into file.sh itself, I don't think that'll work. Modifying a script file while a process is running that file itself tends to cause problems. Anyway, if you put the sed command at the end, by the time the shell gets to it, it will already have done the variable assignments, so it'll be too late. – David Z Feb 11 '18 at 06:48
  • If you're going to edit "file.sh" just put the export commands in. – glenn jackman Feb 11 '18 at 07:26
  • OP asked about doing it from inside the file, so the source + sed solution is no good. The other solution also doesn’t work because they specifically asked to not have all those explicit exports in the file. – user137369 Feb 11 '18 at 11:24
  • If there are spaces inside the environment variables, you'll need to add quotes around them, making this: source <(sed 's/^/export "/' file.sh | sed 's/$/"/') – Isaac Betesh Jul 20 '18 at 20:48