2

Having looked at Setting up environment variables with .sh file and How to permanently set environmental variables I'm still confused as to how to properly set permanent environment variables from a .sh file (I dip in and out of linux use so I'm certainly a novice).

In my specific case I have a setup-env.sh:

# Copyright (c) 2015-2019 LunarG, Inc.

# source this file into an existing shell.

VULKAN_SDK="$(dirname "$(readlink -f "${BASH_SOURCE:-$_}" )" )/x86_64"
export VULKAN_SDK
PATH="$VULKAN_SDK/bin:$PATH"
export PATH
LD_LIBRARY_PATH="$VULKAN_SDK/lib:${LD_LIBRARY_PATH:-}"
export LD_LIBRARY_PATH
VK_LAYER_PATH="$VULKAN_SDK/etc/vulkan/explicit_layer.d"
export VK_LAYER_PATH

I could edit /home/jonathan/.bashrc to contain:

export VK_LAYER_PATH="/home/jonathan/Vulkan/1.2.170.0/x86_64/etc/vulkan/explicit_layer.d"
export VULKAN_SDK="/home/jonathan/Vulkan/1.2.170.0/x86_64"
export LD_LIBRARY_PATH="/home/jonathan/Vulkan/1.2.170.0/x86_64/lib:"

Which is what running . setup-env.sh sets them to.

But this seems awkward and unnecessarily difficult, is there a better way to run a script and have it set permanent environment variables?

5
  • 1
    You could put . setup-env.sh in your ~/.bashrc or ~/.bash_profile or ~/.profile Apr 1, 2021 at 17:34
  • Just curious, what exactly have you copyrighted there?
    – Pourko
    Apr 1, 2021 at 17:36
  • @Pourko This just copy and paste of the setup-env.sh from the Vulkan SDK linux version ( vulkan.lunarg.com/sdk/home#linux). Apr 1, 2021 at 17:41
  • @glennjackman In that case the line would be /path/to/dir . setup-env.sh right? Apr 1, 2021 at 17:42
  • 1
    The other way around, actually. . is the command, so you would want . /path/to/dir/setup-env.sh.
    – terdon
    Apr 1, 2021 at 18:00

2 Answers 2

4

The reason this is complicated is that scripts run in their own sub-shell: a copy of your current environment. So any variables a script sets are discarded as soon as the script exits and returns you to your original shell. However, since it is indeed important to be able to set variables this way, there is a tool for that. You are looking for the . (or source) command:

$ help .
.: . filename [arguments]
    Execute commands from a file in the current shell.
    
    Read and execute commands from FILENAME in the current shell.  The
    entries in $PATH are used to find the directory containing FILENAME.
    If any ARGUMENTS are supplied, they become the positional parameters
    when FILENAME is executed.
    
    Exit Status:
    Returns the status of the last command executed in FILENAME; fails if
    FILENAME cannot be read.

So, in your case, if you want the variables in that file to be set in your current shell, you would do:

$ . /path/to/setup-env.sh

Or, to have it done for every shell you would add this line to your ~/.profile (or, if it exists, your /.bash_profile):

. /path/to/setup-env.sh

You can add it to ~/.bashrc instead, but that would be less efficient since it would be read by every new non-login interactive shell you open (that's what you get when you open a terminal in a graphical Linux system), whereas ~/.profile is only read by login shells so should be read once when you log in and never again. Now, some systems don't source ~/.profile when you log in graphically, so if you find that it doesn't work in ~/.profile, go ahead and add it to ~/.bashrc instead.

Finally, you can simplify that. There's no reason for separate variable definitions and export commands, you can do it in one step:

export VULKAN_SDK="$(dirname "$(readlink -f "${BASH_SOURCE:-$_}" )" )/x86_64"
export PATH="$VULKAN_SDK/bin:$PATH"
export LD_LIBRARY_PATH="$VULKAN_SDK/lib:${LD_LIBRARY_PATH:-}"
export VK_LAYER_PATH="$VULKAN_SDK/etc/vulkan/explicit_layer.d"

Further reading:

1

If it's the period that seems "awkward and unnecessarily difficult", you can do what I do, declare an alias in your .bashrc file. For example:

alias setenv=". ~/path/to/setup-env.sh"

Then just run the command setenv to run it in the current shell. (See help alias for more information.)

2
  • This or source ~/path/to/setup-env.sh in your ~/.profile to do it automatically
    – Garo
    Apr 2, 2021 at 1:37
  • @Garo use . in ~/.profile, not source. The source is a bash-specific alias to the standard . command so since ~/.profile is read by other shells as well, . would be safer.
    – terdon
    Apr 2, 2021 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.