In my case the application is OpenFoam, but this happens also with others Linux programs.
I have a py script (run_test.py) wrote with Windows VS Code:
import subprocess
command = "wsl python3 /mnt/wslg/distro/home/j/test.py"
subprocess.Popen(command, shell=True)
that run another script py (test.py) wrote in Linux VS Code in my WSL:
import subprocess
command = "cd $FOAM_RUN/airfopt && foamRun"
process=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = process.communicate()
if output:
print("Output:", output.decode())
if error:
print("Error:", error.decode())
When i start test.py through Linux VS Code everything works fine, but when i run "run_test.py" i get the error /bin/sh: 1: cd: can't cd to /airfopt
Instead $FOAM_RUN/airfopt if i write the full path /mnt/wslg/distro/root/OpenFOAM/root-11/run/airfopt the new error is /bin/sh: 1: foamRun: not found.
I think because run_test.py run test.py under Windows enviroment and not Linux one. I want run test.py from run_test.py but under Linux env.
The same error running an test.sh file too.
It's my first time with WSL because I need OpenFoam Linux (not blueCFD etc) and connect it to a Windows python script. I search on Google, here... and I also asked chatgpt without getting a good answer.
Thanks to anyone who can help me!
Short version
Examine your
~/.bashrc,~/.bash_profile, and~/.profileto determine where$FOAM_RUNis being set.If it's defined in
~/.bashrc, then move its definition to~/.profileChange your command definition in the first script to:
Also see the bottom of this answer for a better method, but it may be overkill here.
Side-note:
/mnt/wslg/distro/home/j/test.pyis a bit of an odd path. While it works, it should be the same as the shorter/home/j/test.py. The/mnt/wslgmount is used internally by WSLg and may change in the future (it has already changed many times in the past). There is no guarantee that/mnt/wslg/distrowill continue to point to root of the distro in future WSL releases.More detail and other options
Most likely,
$FOAM_RUNis defined in your~/.bashrcor equivalent. This startup config is only sourced when you are starting an interactive shell. When the first Python script runs:There's an implicit call to
bash -cfirst (or whatever your default shell is):By default, when executing a commandline with
-c, Bash does not run interactively, and so~/.bashrcis never read. On some distributions, the stock~/.bashrceven goes further to try to prevent interactive use.You don't mention if running the:
... works from PowerShell or CMD. If my answer is correct, this should fail with the same message.
You have a few options:
First, and probably the right way to do this if you need
$FOAM_RUNto be available in a non-interactive shell, is to move its definition from~/.bashrcto~/.profile. The later is read for login shells. Then have WSL tellbashto run as a login shell so that file will be processed. The command line in the "short version" above:wsl -e bashto start Bash explicitly. This allows us to pass along the options ...-lc: Thelforces a login shell, which forces.profileto be sourced when starting.-cis used to execute the next command (your Python script invocation) in the shell.Another option would leaving the variable definition in
~/.bashrcand then changing your commandline to:The only difference being that we now start Bash with
-iinstead of-l.This tells Bash that you are starting an "interactive" shell and sources
~.bashrc. I generally don't think this is a great idea, because you should be able to assume that an interactive shell can process (obviously) interactive commands - I.e., those that require input.If you do happen to have commands that require input in your
~/.bashrc, then your Python script is going to pause and wait for input. That may not work in asubprocesscall - I can't remember for certain. Regardless, it's probably not what you want to happen in a test script.Finally, the "true and proper" best method is likely to:
$FOAM_RUNin the Windows (calling) Python environmentWSLENVvariable to includeFOAM_RUNas an environment variable that you want to pass from the Windows process to the WSL environment.See Share Environment Vars between WSL and Windows and the corresponding WSL Doc Page for more info.