How do you pass an environment variable from WSL into windows executable - bash

From a Windows Subsystem for Linux (v1) Alpine bash terminal, I would like to set an environment variable that get's passed into a windows executable. Is there any way to do this?
example of what I was hoping would print "Hello, World!":
windows-10:~# export X=World
windows-10:~# cmd.exe /c 'echo Hello, %X%!'
Hello, %X%!
See answer from Philipe below.
Here is a copy of the pertinent info from https://learn.microsoft.com/en-us/windows/wsl/interop
Share environment variables between Windows and WSL
Available in Windows Insider builds 17063 and later.
Prior to 17063, only Windows environment variable that WSL could access was PATH (so you could launch Win32 executables from under WSL).
Starting in 17063, WSL and Windows share WSLENV, a special environment variable created to bridge Windows and Linux distros running on WSL.
Properties of WSLENV:
It is shared; it exists in both Windows and WSL environments.
It is a list of environment variables to share between Windows and WSL.
It can format environment variables to work well in Windows and WSL.
There are four flags available in WSLENV to influence how that environment variable is translated.
WSLENV flags:
/p - translates the path between WSL/Linux style paths and Win32 paths.
/l - indicates the environment variable is a list of paths.
/u - indicates that this environment variable should only be included when running WSL from Win32.
/w - indicates that this environment variable should only be included when running Win32 from WSL.
Flags can be combined as needed.

Can you try this ?
~$ export X=World
~$ export WSLENV=X/w
~$ cmd.exe /c 'echo Hello, %X%!'
Hello, World!

Related

Why is $OSTYPE returning "linux-gnu" on Windows?

Problem
When I run a bash script on Windows:
bash my_script.sh
I get linux-gnu for $OSTYPE inside the script.
Why is this like this?
I assume that i have WSL installed is relevant here.
Tested in PowerShell and CMD.
Git bash is returning msys like expected! Thx #user1934428
Background
I want to start some python scripts from bash, but not inside WSL.
From my command line I reach different python versions on windows, but from inside the bash scripts it is using the one inside WSL (except for GitBash).
You're right, running the bash command in PowerShell or CMD will launch WSL to run your script. You confirm this (and see which version of WSL) by running cat /etc/issue in your bash script. Your WSL environment will have an independent set of environment variables (not just $OSTYPE). You can see this by comparing the output of Get-ChildItem -Path Env:\ in PowerShell to the output of env (after you launch bash from PowerShell).
I suspect that the python version discrepancy you're seeing is a result of the PATH variable in your WSL runtime not matching what you have set in your PowerShell environment. You can fix your version issue by setting an alias containing a path to the python executable you want to use by adding alias python=/c/path/to/python.exe to the start of your bash scripts.
Alternatively, you can use a tool like Cygwin or git-bash to run your scripts. I'm not sure if they will use the same path variables as Windows so you may need to set those manually too.

"export PYTHONPATH = $PYTHONPATH:." in Windows Command Prompt

This Linux command needs to be rewritten for Windows Command Prompt:
export PYTHONPATH = $PYTHONPATH:.
I have researched quite a bit already.
Please note:
This is not necessarily about PYTHONPATH, but about setting an environement variable from Windows command-line (Command Prompt) in an equivalent manner to the Linux code cited above.

msys2 no black window

My screenshot
How can I create a launcher for a program (or a script) on MSYS2 that does not show me the black window of the terminal?
My link:
msys2_shell.cmd -mingw64 -c /c/myfolder/program.exe
To run a program in the MSYS2 environment without showing a window, you should right-click on your Desktop or somewhere else in Windows Explorer, select "New", select "Shortcut", and then enter something like this for the shortcut target:
C:\msys64\usr\bin\mintty.exe -w hide /bin/env MSYSTEM=MINGW64 /bin/bash -lc /c/path/to/your_program.exe
Note that there are 4 paths in here. The path to mintty and your_program.exe are absolute paths that you will need to adjust. The paths to env and bash are relative to your MSYS2 installation directory. Note also that the first path must be a standard Windows path, since Windows expects that when it is running a shortcut.
Explanation
It might seem odd to use MinTTY for this, but the first program we launch needs to be some program that was compiled for the Windows subsystem (-mwindows option to GCC), or else Windows will automatically start a new console when we run the program. We pass the -w hide option to MinTTY to tell it not to actually show its own window. Everything after that option is interpreted by MinTTY as a command to run.
So MinTTY will run /bin/env from the MSYS2 distribution and pass the remainder of the arguments on to it. This is a handy utility that is actually a standard part of Linux as well as MSYS2. It sets the MSYSTEM environment variable to MINGW64 (which is important later) and then it runs /bin/bash with the remainder of the command-line arguments. The MSYSTEM variable selects which of the three MSYS2 environments to use, and the value values for it are MSYS2, MINGW32, or MINGW64.
We pass -l to Bash so that it acts as a login script, and runs certain startup scripts. In particular, the /etc/profile script from MSYS2 is essential because it looks at the MSYSTEM environment variable, sees that it is MINGW64, and then sets a bunch of other environment variables (e.g. PATH) to give you the MinGW 64-bit shell environment, or some different environment if you changed MSYSTEM.
Finally, we pass the name of your program as the main argument to bash, so it will run that program after running the initialization scripts.

DrvFs location of %UserProfile%

From within the Windows Subsystem for Linux, how can I get the DrvFs path that points to what would be %UserProfile% inside the Windows personality? I've seen Access Windows Environment Variables from within Bash in WSL. It seems rather involved for getting one environment variable, and requires hard-coding something from within %UserProfile% anyway ($LXSS_ROOT).
This seems to work:
win_userprofile="$(cmd.exe /c "<nul set /p=%UserProfile%" 2>/dev/null)"
win_userprofile_drive="${win_userprofile%%:*}:"
userprofile_mount="$(findmnt --noheadings --first-only --output TARGET "$win_userprofile_drive")"
win_userprofile_dir="${win_userprofile#*:}"
userprofile="${userprofile_mount}${win_userprofile_dir//\\//}"
Thanks to Craig Loewen at Microsoft for getting me started.
Fortunately since Windows 10 build 17063 (included in Windows 10 1803) there is a more straightforward way of sharing environment variables between Windows and WSL (WSLENV).
To make %USERPROFILE% accessible in WSL you list the variable in the WSLENV variable. If you are not using WSLENV yet then just run this once in Windows:
setx WSLENV USERPROFILE/up
This will cause %USERPROFILE% from Windows to be accessible as $USERPROFILE in WSL shell with Windows path converted to the Unix format. If you do not want to convert the path, just omit the p:
setx WSLENV USERPROFILE/u
More details:
https://learn.microsoft.com/en-us/windows/wsl/interop#share-environment-variables-between-windows-and-wsl
https://devblogs.microsoft.com/commandline/share-environment-vars-between-wsl-and-windows/
I use the variable in my cdw function (cd to Windows path). I define it in ~/.bash_aliases which is executed automatically in Ubuntu:
#!/bin/bash
cdw () {
if test "$#" -eq 0 ; then
cd "$USERPROFILE"
elif test "$1" = - ; then
cd "$1"
else
cd -- "$(wslpath "$#")"
fi
}

View windows environment variables in Cygwin

Is there a way to sync windows environment variables with Cygwin?
For example, in CMD echo %inetroot% gives the path to a project build. Is it possible to transfer this env variable to Cygwin such that echo $inetroot provides the same path?
Thanks!
Use the env program to so that ... or echo "$inetroot". I think the variable names are case-sensitive, though (in Bash and thus MinGW).
Those variables are all available in MinGW from Windows (user profile and global). Again, use env to list them or for example env|grep -i inetroot to find the properly capitalized version of the variable name.

Resources