Environment variables

Environment variables are widely used across Linux to provide convenient access to system and application properties.

Both Snapcraft and snapd consume, set, and pass-through specific environment variables to support building and running snaps.

See below for the various environment variables available to snap applications. For environment variables connected to Snapcraft, see Parts environment variables.

Snap specific environment variables

List environment variables

Each snap runs in a custom environment specifically made for it. To get an overview of the variables in it, you can open a shell as the snap and run the env command.

$ snap run --shell <snap>.<command>
$ env
XDG_VTNR=1
SSH_AGENT_PID=5543
XDG_SESSION_ID=2
SNAP_USER_COMMON=/home/<user>/snap/<snap>/common
SNAP_LIBRARY_PATH=/var/lib/snapd/lib/gl:
SNAP_COMMON=/var/snap/<snap>/common
[...]

Alongside the many system-specific variables, this environment will include the following:

SNAP

Directory where the snap is mounted. This is where all the files in your snap are visible in the filesystem. All of the data in the snap is read-only and cannot be changed.

Typical value: /snap/hello-world/27

SNAP_ARCH

CPU architecture of the running system.

Typical value amd64

Other values are: i386, armhf, arm64.

SNAP_COMMON

Directory for system data that is common across revisions of a snap.

This directory is owned and writable by root and is meant to be used by background applications (daemons, services). Unlike SNAP_DATA this directory is not backed up and restored across snap refresh and revert operations.

Typical value: /var/snap/hello-world/common

SNAP_DATA

Directory for system data of a snap.

This directory is owned and writable by root and is meant to be used by background applications (daemons, services). Unlike SNAP_COMMON this directory is backed up and restored across snap refresh and snap revert operations.

Typical value /var/snap/hello-world/27

SNAP_EUID

This variable contains the effective user ID (euid) of the user running the snap instance. See also SNAP_UID.

For this variable to be exposed by a snap, the snap developer will need to include the following assumes value:

assumes: [snap-uid-envvars]

Requires snapd 2.59+.

SNAP_INSTANCE_NAME

The name of snap instance, including instance key if one is set (snapd 2.36+).

For example snap hello-world with instance key foo has instance name equal to hello-world_foo.

Typical value: hello-world

SNAP_INSTANCE_KEY

Instance key if one was set during installation or empty (snapd 2.36+).

For example instance hello-world_foo has an instance key foo.

Typical value: none

SNAP_LIBRARY_PATH

Directory with additional system libraries. This variable is used internally by snapcraft.

The value is always /var/lib/snapd/lib/gl: Please note the colon at the end of that value, the variable is a colon-separated list.

The referenced directory is typically empty unless Nvidia proprietary drivers are in use.

SNAP_NAME

The name of the snap as specified in the snapcraft.yaml file.

Typical value: hello-world

SNAP_REAL_HOME

The vanilla HOME environment variable before snapd-induced remapping, refer Any way to acquire the originally set HOME environment variable? - snapcraft - snapcraft.io for more info.

Available since snapd 2.46.

SNAP_REVISION

Revision of the snap, as allocated by the Snap Store on upload or as allocated by snapd for locally installed snaps.

The Snap Store assigns monotonic revisions to each upload of a given snap. Snapd uses Snap Store revisions if accompanying assertions are available or uses a locally generated number. Locally generated numbers are prefixed with x to distinguish them from Snap Store uploads.

Typical value: 27 or x1

SNAP_SAVE_DATA

This variable is only exposed on Ubuntu Core systems, and was introduced with snapd 2.57.

It points to a snap-specific location on the ubuntu-save partition where the snap is allowed to store persistent files (like certificates or configuration files) that will survive a factory reset of the Ubuntu Core device.

See ubuntu-save in the Ubuntu Core documentation for more details on storage layout with this specific partition.

SNAP_UID

This variable contains the user ID (uid) of the user running this snap instance. See also SNAP_EUID.

For this variable to be exposed by a snap, the snap developer will need to include the following assumes value:

assumes: [snap-uid-envvars]

Requires snapd 2.59+.

SNAP_USER_COMMON

Directory for user data that is common across revisions of a snap.

Unlike SNAP_USER_DATA, data present in this directory is not backed up or restored across snap refresh and snap revert operations. The directory is suitable for large data that the application can access even if it was made or modified by a future version of a snap.

Typical value /home/zyga/snap/hello-world/common

SNAP_USER_DATA

Directory for user data.

This directory is backed up and restored across snap refresh and snap revert operations.

Typical value: /home/zyga/snap/hello-world/27

The final number there is $SNAP_REVISION.

SNAP_VERSION

The version string as specified in the snapcraft.yaml

Typical value 6.3

Generic variables

HOME

For non-classic snaps, this environment variable is re-written to SNAP_USER_DATA by snapd so that each snap appears to have a dedicated home directory that is a subdirectory of the real home directory.

For classic confinement snaps, the value remains unchanged.

Typical value: /home/_user_name_/snap/_snap_name_/_snap_revision_ (e.g. /home/zyga/snap/hello-world/27)

PATH

This environment variable is re-written by snapd so that it is consistent with the view of the filesystem presented to snap applications.

The value is always:

  • For non-classic confinement snaps:

    $SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
    
  • For classic confinement snaps:
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

1 Like

Can you please add that accessing the SNAP_USER_COMMON and SNAP_USER_DATA require the ‘home’ plug to be connected?

I’m pretty sure this isn’t the case:

$ snap interfaces nano
Slot  Plug
-     nano:home
-     nano:removable-media
$ snap run --shell nano
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

$ ls
ls: cannot open directory '.': Permission denied
$ cd $SNAP_USER_COMMON/
$ touch test
$ cd $SNAP_USER_DATA/
$ touch test

Ok, thank you for testing that!

I think the HOME environment variable is a bit under specified?

For classic confined apps, it is set to /home/<user_name>. This is surely by design no?

Classic confinement is effectively un-confining the applications inside a snap. Applications which use classic confinement have the same full system access as traditionally packaged applications. Classic confinement is intended as a stop-gap measure to enable developers to publish applications which need more access than the current set of interfaces enable. Over time, as more interfaces are developed, snap publishers can migrate away from classic confinement to strict.

Should this not be added into the description for the HOME environment variable?

It would also be useful to be aware of which environment variables are guaranteed I guess. Can these variables be relied on to guarantee the location of a mounting point for example?

On Arch for example, the wiki currently implies that SNAPs may not be mounted under /snap. But it is necessary for classic confinement SNAPs. Does this mean these environment variables will reflect the changes? Will they give the hard path or the symbolically linked path?
https://wiki.archlinux.org/index.php/Snap

Then there is the SquashFS documentation which seems to imply that the snap will be mounted under /snap for predictability and deterministic behaviour.

The documentation in this case is a bit inconsistent and should be more concrete no?

$PATH in devmode snap is different when running snap run --shell than when running the actual snap application.

I’ve created this basic snap to illustrate this. If you pull that down, then you can see the following:

$ snapcraft
$ snap install --devmode testsnap_0.1.0_amd64.snap
$ testsnap
/snap/testsnap/x2/usr/sbin:/snap/testsnap/x2/usr/bin:/snap/testsnap/x2/sbin:/snap/testsnap/x2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

# Whereas
$ snap run --shell testsnap
robin@rt480:/home/robin/Projects/testsnap$ ./testsnap 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

(The testsnap binary simply contains echo $PATH)

This caused me no end of confusion for a while. I assume this is a bug?

When you launch a snap application, it’ll execute an “adapter” script installed by Snapcraft to set the appropriate PATHs and other environment variables
, currently when you run snap run --shell this process won’t happen unless you’re using the full adapter.

Thanks for helping me understand a bit better.

But this still feels like a very jarring broken experience. I’m not going to say whether the fix would be to run the “adapter” script when running --shell or something else.

Do you think I should file this as an issue against snapd or snapcraft?

This should no longer be a problem after you set the apps._app_name_.adapter property to full (which should be the default in future Snapcraft).

1 Like

Ah so you’re saying this will soon work intuitively out of the box? Any idea when that might land?

you’re saying this will soon work intuitively out of the box?

Well that’s what documented in the source comments, I have no idea when it will really be a thing.

1 Like

Thanks for the heads up, I’ve updated the description.

1 Like

Hello,

it may be just that I missed it, but I’m thinking I could use an env variable that provides a USER_DATA_PATH with the “current” snap revision ‘wildcard’ in it.

I would be using whatever it returns as a basis for constructing a default for a user-modifiable path setting in my app, that works across revisions of my snap.

(So I’d “typically” like to construct the

/home/username/snap/snapname/current/mystuffgoeshere/

path instead of the

/home/username/snap/snapname/x123/mystuffgoeshere/

since /home/username/snap/snapname/x123/mystuffgoeshere/ becomes inaccessible after a snap refresh, and the path should update to /home/username/snap/snapname/x124/mystuffgoeshere/, which then feels dodgy if done automagically)

and I guess I need

/home/username/snap/snapname/current/

as a basis. Is there an envrionment variable now to provide that? Is there a best practice to construct the value if not (I’ll likely do some string replacement for starters), and shouldn’t there be a variable/recipe?

Or is it just a stupid question, do such values pose a risk I didn’t spot at first?

Thank you!

From the entry for SNAP_LIBRARY_PATH:

" The value is always /var/lib/snapd/lib/gl:"

For my test (hello-world) snap, it’s slightly more involved:

SNAP_LIBRARY_PATH=/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void

Not sure if that distinction needs to be clarified.

The inconsistency is due to the code change in the subsequent snapd releases, the content will likely not be stable and would need to be updated time-to-time.

We probably should just point to the source code where this variable is determined instead of duplicating them in the documents.

That sounds reasonable.

There’s a grammar mistake in SNAP_COMMON:

“Unlike SNAP_DATA this directory does is not backed up”

1 Like

Fixed - thank you for letting us know!

1 Like

It’s pretty cool to be able to list these environment variables, but how can we edit them? I want to pass a specific JAVA_HOME to gradle, but I have a hard time finding any information about this in the documentation…

Thanks for asking this question. I’ll try to make this information easier to find, but you should be able to pass a specific JAVA_HOME using build-environment within the part, eg:

    plugin: gradle
    [...]
    build-environment:
      - JAVA_HOME: /usr/lib/jvm/java-11-openjdk-amd64

This behaviour is briefly discussed here:

Another useful tip is to search GitHub for projects trying to do the same thing: https://github.com/search?q=filename%3Asnapcraft.yaml+%22plugin%3A+gradle%22+%22JAVA_HOME%22&type=Code

1 Like