{"id":2005,"date":"2017-12-22T13:52:04","date_gmt":"2017-12-22T21:52:04","guid":{"rendered":"http:\/\/blogs.msdn.microsoft.com\/commandline\/?p=2005"},"modified":"2020-05-28T10:34:40","modified_gmt":"2020-05-28T17:34:40","slug":"share-environment-vars-between-wsl-and-windows","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/commandline\/share-environment-vars-between-wsl-and-windows\/","title":{"rendered":"Share Environment Vars between WSL and Windows"},"content":{"rendered":"<p>Hey WSL users\u2014we have more features to share with you! Our latest Windows Insider build lets you share environment variables between WSL and Windows. Starting with <strong>Build 17063<\/strong>, let\u2019s look at how you can leverage the new \u201cWSLENV\u201d to enhance environmental variable interop between Win32\/WSL.<\/p>\n<h2>Summary<\/h2>\n<p>For the pros who\u2019ve already heard about WSLENV and just want to know how it works, see below for a quick synopsis:<\/p>\n<ul>\n<li>WSLENV is a colon-delimited list of\u00a0environment variables that should be included when launching\u00a0WSL processes from Win32 or Win32 processes from WSL<\/li>\n<li>Each variable can be suffixed with a slash followed by\u00a0flags\u00a0to specify how it is translated<\/li>\n<li>The value is a path that should be translated between WSL paths and Win32 paths<\/li>\n<li>The value is a list of paths. In WSL, it is\u00a0a colon-delimited list. In Win32, it is a semicolon-delimited list<\/li>\n<li>The value should only be included when invoking\u00a0WSL from Win32<\/li>\n<li>The value should only be included when invoking Win32 from WSL<\/li>\n<li>You can set WSLENV in .bashrc or in the custom\u00a0Windows environment for your user<\/li>\n<\/ul>\n<p>A sample of how a WSLENV could possibly look:<\/p>\n<pre><code>WSLENV=GOPATH\/l:USERPROFILE\/w:SOMEVAR\/wp\n<\/code><\/pre>\n<h2>What are Environment Variables?<\/h2>\n<p><span style=\"color: #000000;font-family: Calibri\">Environment variables are a way to store configurable values across your entire system\u2014all your programs have access to these. On Windows, you can find your environmental variables by going to \u201cEdit environment variables for your account\u201d in the Control Panel. It will show a window like the one below:<\/span><\/p>\n<p><img decoding=\"async\" width=\"618\" height=\"585\" class=\"alignnone size-full wp-image-2015\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/envvar.png\" \/><\/p>\n<p>Notice the wide range of values in the example above\u2014lists of directories, software versions, locations where temporary files are permitted to be stored, and more.\u00a0\u00a0 Who sets these values? You can, newly installed software on your system can, or Windows has set some of them.<\/p>\n<p>An example of a well-known environmental variable is PATH. Much like the name implies, PATH contains a list of directories (paths) separated by a semi-colon which point to the locations of numerous executables. Here\u2019s a common example of how PATH is used:<\/p>\n<p><img decoding=\"async\" width=\"979\" height=\"512\" class=\"alignnone size-full wp-image-2016\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/path.png\" \/><\/p>\n<p>I\u2019m about to invoke Node from the command line. When I enter this command, cmd reads the contents of PATH, searching for a directory that contains the executable \u201cnode.exe\u201d. If it finds it, it stop the search immediately and invokes the executable it found. The image above has PATH printed to the console\u2014and you\u2019ll notice that the last entry in PATH points to a directory which does in fact contain Node.<\/p>\n<h2>WSL and environment variables &#8212; before Insider 17063<\/h2>\n<p>Referencing environment variables from *both *Windows and WSL introduces interop issues. Prior to 17063, the only Windows environment variable that WSL had access to was PATH (so you could launch Win32 executables from under WSL). But there was no way to set an environment variable in WSL, invoke a Win32 process, and expect for that variable to be fed through to the process.<\/p>\n<p>Given these limitations, you couldn\u2019t pass an environment var in WSL to a Win32 process without jumping though convoluted hoops. Since passing environment vars to processes is a common practice and we received plenty of feedback concerning how this was a pain \u00a0point for our users, we wanted to make this a better experience.<\/p>\n<h2>WSL and environment variables &#8212; after Insider 17063<\/h2>\n<p>We\u2019re introducing a special environmental var named WSLENV to assist in the flow between WSL and Win32. WSLENV is shared; it exists in both environments. A user sets the value of WSLENV to a concatenation of several other already-defined environment vars\u00a0\u00a0, each suffixed with a slash followed by flags to specify how the value should be translated. \u00a0An example definition could be something like this:<\/p>\n<pre><code>WSLENV=HOME\/w:GOPATH\/l:TMPDIR\/p \u2026\n<\/code><\/pre>\n<p>There are four flags you can use to influence how they\u2019re translated. Let\u2019s walk through each:<\/p>\n<h3>\/p<\/h3>\n<p>This flag indicates that a path should be translated between WSL paths and Win32 paths. Notice in the example below how we set the var in WSL, add it to WSLENV with the \u2018\/p\u2019 flag, and then read the variable from cmd.exe and the path translates accordingly.<\/p>\n<p><img decoding=\"async\" width=\"979\" height=\"512\" class=\"alignnone size-full wp-image-2026\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/flag_p.png\" \/><\/p>\n<h3>\/l<\/h3>\n<p>This flag indicates the value is a list of paths. In WSL, it is\u00a0a colon-delimited list. In Win32, it is a semicolon-delimited list. See in the example below how PATHLIST is appropriately converted to a semi-colon separated list.<\/p>\n<p><img decoding=\"async\" width=\"979\" height=\"512\" class=\"alignnone size-full wp-image-2035\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/flag_l.png\" \/><\/p>\n<h3>\/u<\/h3>\n<p>This flag indicates the value should only be included when invoking\u00a0WSL from Win32. In the example below, we set FORWSL from cmd and it will show up in WSL.<\/p>\n<p><img decoding=\"async\" width=\"979\" height=\"512\" class=\"alignnone size-full wp-image-2085\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/flag_u2.png\" \/><\/p>\n<p>Notice how it does not convert the path automatically\u2014we need to specify the \/p flag to do this. We can combine flags and do just that:<\/p>\n<p><img decoding=\"async\" width=\"979\" height=\"512\" class=\"alignnone size-full wp-image-2095\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/flag_up.png\" \/><\/p>\n<h3>\/w<\/h3>\n<p>This flag indicates the value should only be included when invoking Win32 from WSL.<\/p>\n<p><img decoding=\"async\" width=\"979\" height=\"512\" class=\"alignnone size-full wp-image-2075\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/33\/2019\/02\/flag_w1.png\" \/><\/p>\n<h3>Passing vars with a script<\/h3>\n<p>If you&#8217;re writing a bash script and want to pass environment variables to some process that you will be invoking, you can do this:<\/p>\n<pre><code class=\"bash\">#!\/bin\/bash\n\n#some logic here...\n\nexport MYPATH=\/mnt\/c\/Users\/\n\n#invoke the process and pass the env var in one go:\nWSLENV=$WSLENV:MYPATH\/p process.exe\n<\/code><\/pre>\n<p>One important thing to call out here is that I am\u00a0<span style=\"text-decoration: underline\">appending<\/span> the environment variable I want to pass to the process to WSLENV. We recommend this so you don&#8217;t wipe out the other vars previously set for WSLENV.<\/p>\n<h2>An Example with Go<\/h2>\n<p>For example, say you want to set up a dev environment with <a href=\"https:\/\/golang.org\/\">Go<\/a> in WSL. With the WSLENV var, we can configure it to share GOPATH between WSL and Win32. If you&#8217;ve never used Go before,\u00a0 if your project directory is outside of the root directory where Go is installed then you need to set <a href=\"https:\/\/github.com\/golang\/go\/wiki\/GOPATH\">GOPATH<\/a>. Let&#8217;s walk through an end-to-end example.<\/p>\n<h4>1&#46; Install Go on Windows &amp; WSL<\/h4>\n<p>First, we need to install Go on both platforms. To install on Windows, <a href=\"https:\/\/golang.org\/dl\/\">grab Go<\/a> and select Windows as your platform. Click through and complete the installation. Next, install Go in WSL. We need to issue this command from WSL:<\/p>\n<pre><code>sudo apt-get install golang\n<\/code><\/pre>\n<h4>2&#46; Grab VSCode<\/h4>\n<p>Next, we&#8217;ll want to install VSCode in Windows. If you don&#8217;t already have VSCode, you can get it from <a href=\"https:\/\/code.visualstudio.com\/\">here<\/a>.<\/p>\n<h4>3&#46; Set up the project<\/h4>\n<p>Next, we need to set up our Go project. The project needs to be under the Windows file system (I&#8217;ll just make mine on my Desktop). Issue the following commands in PowerShell:<\/p>\n<pre><code class=\"cmd\">mkdir $env:USERPROFILE\\desktop\\goProject\ncd\u00a0$env:USERPROFILE\\desktop\\goProject\nNew-Item hello.go\n<\/code><\/pre>\n<p>Open the newly created hello.go file with VSCode or your favorite text editor and add this text to it:<\/p>\n<h4>4&#46; Set Environment Variables<\/h4>\n<p>Now we need to set our GOPATH to point to this project, and then add GOPATH to WSLENV. From PowerShell:<\/p>\n<pre><code class=\"cmd\">setx GOPATH \"$env:USERPROFILE\\desktop\\goProject\"\nsetx WSLENV \"$env:WSLENV:GOPATH\"\/p\n<\/code><\/pre>\n<h4>5&#46; Success<\/h4>\n<p>That&#8217;s all you need to do. If you open the project file in VSCode, it will prompt you about missing package&#8211;click yes to install these. After they complete their installation, you will have full VSCode integration (intellisense, linting, etc).\u00a0On the WSL side, now if you navigate to your project directory (it will be under \/mnt\/c\/&#8230;) and try to &#8220;go build&#8221;, it will run successfully and output a Linux binary that you can run in WSL. Debugging from VSCode will produce a Windows executable that you can also run.<\/p>\n<h2>Conclusion<\/h2>\n<p>We hope using the new WSLENV environment variable will help with interoperating between WSL and Win32. Grab Insider Build **17063 **to try it out. We would love to get feedback on this feature. Is it too clunky? does it work the way you\u2019d hoped? Leave a comment below and let us know.<\/p>\n<h2>FAQ<\/h2>\n<h3>What happens if I set an environment var in WSLENV from Win32 which is already defined in WSL?<\/h3>\n<p>The definition in WSL (via .profile or other) will override the value defined in WSLENV when accessed via WSL.<\/p>\n<h3>What about the other way around (variable defined in Win32, then defined and shared from WSL?)<\/h3>\n<p>The WSLENV definition will override the value previously defined in Win32 (the opposite of the above question).<\/p>\n<h3>What happens if I concatenate WSLENV to the end of my PATH environment var?<\/h3>\n<p>It will not concatenate anything\u2014WSLENV gets chopped off.<\/p>\n<h3>Do the changes I make to WSLENV from WSL persist after I close WSL?<\/h3>\n<p>No, you\u2019ll need to modify the appropriate config file (.profile, .bash_rc, etc) and set WSLENV to whatever you\u2019d like.<\/p>\n<h3>Can I set WSLENV to an actual filesystem path or does it have to be set to an existing environment var?<\/h3>\n<p>You can set the value to whatever you\u2019d like. Although, if you were to set a filesystem path, no translation occurs. That\u2019s why we recommend setting WSLENV to the environment variable <u>containing<\/u> the path and you\u2019ll get the path-translation flags for free.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey WSL users\u2014we have more features to share with you! Our latest Windows Insider build lets you share environment variables between WSL and Windows. Starting with Build 17063, let\u2019s look at how you can leverage the new \u201cWSLENV\u201d to enhance environmental variable interop between Win32\/WSL. Summary For the pros who\u2019ve already heard about WSLENV and [&hellip;]<\/p>\n","protected":false},"author":1035,"featured_media":4349,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2,3,5,9],"tags":[29,31,41,72],"class_list":["post-2005","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-command-line","category-linux-tools","category-windows-10","category-bash-on-ubuntu-on-windows","tag-command-line","tag-console","tag-interop","tag-wsl"],"acf":[],"blog_post_summary":"<p>Hey WSL users\u2014we have more features to share with you! Our latest Windows Insider build lets you share environment variables between WSL and Windows. Starting with Build 17063, let\u2019s look at how you can leverage the new \u201cWSLENV\u201d to enhance environmental variable interop between Win32\/WSL. Summary For the pros who\u2019ve already heard about WSLENV and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/posts\/2005","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/users\/1035"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/comments?post=2005"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/posts\/2005\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/media\/4349"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/media?parent=2005"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/categories?post=2005"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/commandline\/wp-json\/wp\/v2\/tags?post=2005"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}