When I run bash.exe in Git for Windows from WSL bash, I want to pass PATH from WSL to Win32, and filter out //wsl$/*** items in Win32 bash scripts. So I tried echo ${PATH//\/\/wsl\$+([^:]):/} but it takes several seconds to run.
My Win 10 is v1903 x64, WSL bash is from Ubuntu, and Git for Windows is v2.22.0.windows.1 . My CPU is Intel E3-1230 v5 .
The below is how I get a $PATH including //wsl$ :
open WSL bash, modify $PATH and export it
run WSLENV=PATH/l start2.exe /d/Git/usr/bin/bash.exe to get a new console window of bash.exe in Git for Windows
start2.exe is a tool of mine just to run exe in another console
echo $PATH shows something like /mingw64/bin:/usr/bin:/d/Program Files/nodejs://wsl$/Ubuntu/mingw64/bin:...
But in my computer, access to //wsl$/Ubuntu/*** is denied after once system upgrading. So I need to remove these //wsl$/* items from $PATH, otherwise the bash.exe seems to run slowly.
I tried export PATH="$(echo "$PATH" | sed -r 's|//wsl[^:]+:||g')" and it worked, but I want to use built-in commands to do so (the code below has been edited):
shopt -s extglob
if [[ $PATH == *//wsl\$* ]]; then
PATH=${PATH//\/\/wsl\$+([^:]):/} # this line takes seconds
fi
I expect it runs quickly, but the code above is very very slow.
Added:
The main problem is my PATH is dynamic in WSL bash, and can even be changed by myself, so I can not pre-set a constant PATH for Git for Windows's bash.
Related
When I run basic commands like pwd and cd the command itself executes fast but the console hangs for 1 second before allowing me to execute another command.
I got the latest Git Bash portable and tried
32- and 64-bit
Run as admin
sh.exe instead of git-bash.exe (and Run as admin)
But Cygwin does not have this problem.
In Cygwin, running pwd from the same directory as any Git Bash variant results in equally fast command completion but also there is no console hanging.
My Windows is: Version 10.0.19044 Build 19044
I have nVidia Quadro P3000
UPDATE from comments below:
It appears to be an issue with my Git installation but I chose the defaults so I don't know what it could be.
When I execute PS1='$ ' in Git-Bash, I do not have the the 1-second pause after each command is executed.
UPDATE from comments below
$ echo ${PS1#A}
declare -x PS1='\[\033]0;$TITLEPREFIX:$PWD\007\]\n\[\033[32m\]\u#\h \[\033[35m\]$MSYSTEM \[\033[33m\]\w\[\033[36m\]`__git_ps1`\[\033[0m\]\n$ '
I did not change anything.
I download a version of portable Git For Windows, launch as admin and type ls, pwd, etc.
I went back to 2.24 but same behavior.
I'm also going to try it on my personal PC since it could be my corporate antivirus that's causing this.
UPDATE
The issue is __git_ps1 and there's an open issue
I think that __git_ps1 is the culprit.
As a test, put following code in /tmp/experiment.sh
if [[ "$(type -t __git_ps1)" == 'function' ]]; then
cd(){
builtin cd "$#"
__GIT_PS1=$('__git_ps1') # Calling original __git_ps1, only when changing directory.
}
__git_ps1_stub(){
echo "$__GIT_PS1" # Now $PS1 will do this echo, instead of calling __git_ps1
}
alias __git_ps1=__git_ps1_stub # __git_ps1_stub will be called in $PS1
cd . # Initialize $__GIT_PS1 for the first time.
fi
Then start a git-bash terminal, and run source /tmp/experiment.sh
If situation improves, you can put the code in ~/.bashrc
You'll need to change other commands (like pushd, popd, etc) if you use them to change directory.
Try first to simplify your PATH when testing your Git bash.
In a CMD, type
set "GH=C:\Program Files\Git"
set "PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0"
set "PATH=%GH%\bin;%GH%\cmd;%GH%\usr\bin;%GH%\mingw64\bin;%GH%\mingw64\libexec\git-core;%PATH%"
Then try again and type bash to enter a shell session.
By default, I get:
$ echo $PS1
\[\033]0;$TITLEPREFIX:$PWD\007\]\n\[\033[32m\]\u#\h \[\033[35m\]$MSYSTEM \[\033[33m\]\w\[\033[36m\]`__git_ps1`\[\033[0m\]\n$
And it is quite fast.
(Microsoft Windows 10.0.19044.1586, git version 2.35.1.windows.2)
The problem may be related to slow resolution of computer network names. Since the computer name is involved in the command line. I advise you to add yourhostname and localhost to etc/hostname.
For me it was corrupt page file. Try clearing Windows page file and rebooting. Page file was constantly causing my git bash to hang for 20 seconds with just carriage returns. I've re-enabled page file several times and eventually it happens again. Clearing page file fixed it every time.
I turn page file completely off now and git bash is screaming fast.
I recently installed MSYS2 with Emacs (64-bit) and am currently calling that Emacs from a Windows shortcut. It works fine, exactly like if I had downloaded the Emacs executable for Windows and unzipped it somewhere. Which is to say, it picks up all of my Windows environment variables and such.
For various reasons, I would prefer to run Emacs from an MSYS2 bash shell and use the environment variables in that shell. As it stands, I can open an MSYS2 MINGW64 shell, type emacs on the command line, and everything works the way I want it to.
Now I would like to package the whole thing up into either a one-liner I can stuff into to a Windows shortcut or a script I can call from a Windows shortcut. With the help of this post, I came up with the following:
C:\msys64\bin\mintty.exe /bin/env MSYSTEM=MINGW64 /bin/bash -l -c /mingw64/bin/emacs
This successfully opens Emacs, but fails to load the .bashrc file that I source in .bash_profile in the usual manner:
if [ -f "${HOME}/.bashrc" ] ; then
source "${HOME}/.bashrc"
fi
I define a function in .bashrc that I call in .bash_profile, so this is kind of important. It did not take much effort to realize that the problem is that HOME is not defined, so .bashrc is simply not found. However, if I define HOME like so:
C:\msys64\bin\mintty.exe /bin/env HOME=/home/alanhr MSYSTEM=MINGW64 /bin/bash -l -c /mingw64/bin/emacs
I get exactly the same result: .bashrc is not found and my function is not executed. Here's where it gets weird. If I simply leave off the call to emacs like so:
C:\msys64\bin\mintty.exe /bin/env HOME=/home/alanhr MSYSTEM=MINGW64 /bin/bash -l
I get a bash shell where .bashrc has been loaded correctly and my function is correctly executed. I can type emacs on the command line and have it function exactly as I want it to.
This feels like a classic case of missing something that is right under my nose, but I have read the bash man page to no avail. Does anyone have any idea how I can make this work?
It is the -i option to load .bashrc. The following works for me:
C:\msys64\usr\bin\mintty.exe -w hide /bin/env MSYSTEM=MINGW64 /bin/bash -l -i -c /mingw64/bin/emacs
I have a simple, already-working bash script set up to launch specific files with specific programs in the gaming frontend EmulationStation on Windows.
But the frontend routes its actions through a Command Prompt. And when Command is used to run the script through Bash, the Bash shell just opens and then closes immediately.
Here's an image of what shows for the instant before Bash closes.
This is only happening when going through a separate Command Prompt first, such as Windows Command Prompt or Git Command Prompt. Running the script with an appropriate argument directly through the git-bash shell works just fine.
In case you want to see the script for any reason, here it is:
#!/bin/bash
defaultemulaunch="V:/Emulation/.emulationstation/systems/retroarch/retroarch.exe -L "V:/Emulation/.emulationstation/systems/retroarch/cores/bsnes_mercury_accuracy_libretro.dll" \"$1\""
emu1names=(\
"(1999) Fire Emblem - Thracia 776.smc")
emu1launch="V:/Emulation/.emulationstation/systems/retroarch/retroarch.exe -L "V:/Emulation/.emulationstation/systems/retroarch/cores/snes9x_libretro.dll" \"$1\""
gamename=`basename "$1"`
for index in ${!emu1names[*]}
do
game=${emu1names[index]}
if [ "$game" == "$gamename" ]; then
eval "$emu1launch"
fi
done
eval "$defaultemulaunch"
But it's worth pointing out that this is happening when trying to run any bash script when starting the process from a separate Command Prompt.
Note: Git is installed on the hard drive that houses the emulation frontend (V:)---not in the user directory or programs directory of the system's OS/boot drive (C:). I mention this because git-bash's failure at an apparent "login" step except when launched directly feels like it could be a default filepath issue.
Check if that program would still open/close a Windows when executed from the CMD with:
bash -c '/v/path/to/bash/script'
In your case:
set PATH=V:\Emulation\
set GIT_HOME=V:\Emulation\Git
set PATH=%GIT_HOME%;%GIT_HOME%\bin;%GIT_HOME%\usr\bin;%GIT_HOME%\mingw64\bin;%PATH
Then:
cd V:/Emulation/.emulationstation/roms/snes/
bash -c './gamelaunch.sh "./(1990) F-Zero.sfc"'
I usually make a run.bat script which would:
set the correct PATH
launch the correct script
That way, for any of my project, I just type run.
And it runs.
I have installed Atom editor natively on Windows 10 by downloading an running the installer. Now I start WSL Ubuntu distro and want to start Atom (atom-editor) from there with the command atom . or VSCode (visual-studio-code) with the command code .
Atom starts, but not in the directory where the command was executed, instead it shows files from C:\\Windows. Moreover Ubuntu WSL terminal shows following error message:
atom .
grep: /etc/wsl.conf: No such file or directory
"\\wsl$\Ubuntu-18.04\home\wlad\projects\udemy\flask-bootcamp\Flask-Bootcamp-master"
CMD.EXE wurde mit dem oben angegebenen Pfad als aktuellem Verzeichnis gestartet.
UNC-Pfade werden nicht unterstützt.
Stattdessen wird das Windows-Verzeichnis als aktuelles Verzeichnis gesetzt.
Sorry it's German localized but it says something like UNC-paths are not supported
(haven't tested VSCode yet)
So how can I use Atom or VSCode editor installed on Windows 10 from within WSL?
** UPDATE **
As of today (April 2020) there is a much better way to use VSCode on Windows w/ WSL, VirtualMachines (VM) and even Containers. Check out remote-development plugin for VSCode.
I created a short script to handle the three atom commands I use most (I use Ubuntu with WSL):
atom
atom .
atom RELATIVE_PATH_FILE
This script is not optimized, and I'm sure many people will find edge cases, but it gets the job done for me. To use it, simply placed it in ~/.local/bin/atom and make it executable by running chmod +x ~/.local/bin/atom. You may need to restart your shell for ~/.local/bin to be added to your path. In order to simplify things a bit, I mapped the WSL network drive for my ubuntu installation to U:, so you'll either want to do the same or modify the script accordingly on line 9.
#!/bin/bash
if [ -z $1 ]; then
pushd /mnt/c > /dev/null
/mnt/c/Windows/System32/cmd.exe /c "atom"
else
[[ $1 = "." ]] && path=$(pwd) || path=$(realpath $1)
winPath=$(echo "U:$path" | sed -e 's/\//\\/g')
pushd /mnt/c > /dev/null
/mnt/c/Windows/System32/cmd.exe /c "atom $winPath"
fi
popd > /dev/null
The script performs a few simple steps. First, if there is no command line argument, it simply calls atom using cmd.exe without arguments. If the command line argument is ., it gets the path to the current directory, otherwise, it gets the absolute path to the given file using realpath. The path is converted from POSIX to Windows format using sed before calling atom using cmd.exe as before, but with the path argument.
The pushd and popd commands are just there to get rid of the annoying warning message about UNC paths not being supported:
...
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported. Defaulting to Windows directory
In the "Known issues" section of the blog post #Wlad mentioned, there states
Accessing Linux files is treated the same as accessing a network resource, and any rules for accessing network resources will still apply e.g: When using CMD, cd \\wsl$\Ubuntu\home will not work (as CMD does not support UNC paths as current directories), however copy \\wsl$\Ubuntu\home\somefile.txt C:\dev\ will work
So as Atom may use cmd.exe to launch itself from the command line (maybe some batch file), and given the fact that cmd.exe cannot open network resources as current directory (which WSL directory is treated as), there came the failure as you attempted to launch Atom from WSL shell.
Actually, in VS Code there is a better solution to launch VS Code directly from the WSL shell: VS Code Remote.
You can take the following steps to enable VS Code to be directly launched from WSL shell:
Install the extension Remote - WSL to VS Code on the Windows side;
Then when you type code . in your WSL shell, VS Code Remote Server will be automatically installed, and VS Code will soon launch.
By using VS Code Remote, you can not only open the directory in VS Code, but can also be benefited in many other aspects: for example, you can use the WSL shell as the integrated shell in VS Code and run programs in WSL directly from VS Code.
Here is the official doc for VS Code Remote - WSL.
The script in Eduardo's answer is a great approach, but didn't allow to open multiple directories/repos at once (e.g. atom terraform-modules terraform-repo), which I do often.
The following is my twist on it:
#!/bin/bash
winPathPrefix="U:"
function convertToWinPath() {
echo "${winPathPrefix}$(realpath ${1})" | sed -e 's/\//\\/g'
}
declare -a atomCmd=(/mnt/c/Windows/System32/cmd.exe /c "atom")
for path in "$#"; do
atomCmd+=($(convertToWinPath ${path}))
done
${atomCmd[#]} 2>/dev/null
That is entirely based on Eduardo's script and should allow a more general use case
Wanting to run Atom from WSL got me here but unfortunately the accepted answer does not mention atom and the other atom related workarounds don't work anymore.
In case someone googles the question and ends up here. Here's an actual workaround (It will break in new Atom updates).
Add the following path path in the windows enviroments: C:\Users\{username}\AppData\Local\atom\app-{version}\ (at the time of this post the version is 1.60.0 so app-1.60.0.
Use the path mentioned above as the default path contains a bash executable that will be run fail to run in wsl.
Here's where it will break in future updates. The fix is to update the env in windows to the new path since the folder where the exe is located will change to match atom's version.
Add the following in your .bashrc or .zshrc:
Important to be added in .bashrc or .zshrc as making a separate script in /usr/bin will always make atom to open in the C:/Windows folder.
function _atom () { exec nohup atom.exe "$#" &> /dev/null & } # Do not output in terminal and do not block the terminal. Also send the command arguments to atom.
alias atom="_atom"
Open a new wsl terminal.
I wrote a bash script to open atom with and without files from WSL2. It can handle any number (including 0) of file arguments, on any drive. Both relative and absolute paths are supported, but it can't handle path name containing .. or ~. Pointing atom to a director also works as expected. Here's my script:
#!/bin/bash
atom_cmd="/mnt/c/Users/`whoami`/AppData/Local/atom/atom.exe"
for i in "$#"; do
if [[ $i == /mnt* ]]; then
linPath="$i" #for absolute file paths
else
linPath="`pwd`/$i" #for relative file paths
fi
if [[ $linPath == *".."* || $linPath != "/mnt"* || $i == "/home"* ]] ; then
echo "atom script is unacceptable file path $linPath"
continue 1
fi
winPath="\""`echo $linPath | sed -e 's|\/mnt\/\([a-z]\)|\u\1:|' -e 's:\/:\\\\:g'`""
atom_cmd="$atom_cmd $winPath\""
done
unset linPath
unset winPath
echo "command:" "$atom_cmd"
eval "$atom_cmd"
unset atom_cmd
(I'm sure there are things to improve about this, like edge cases and better use of language features. I'd welcome suggestions.)
this can be a little bit outdated but you can simply run a powershell and use:
wsl.exe -d Ubuntu-20.04 //In my case ubuntu
This should open a ubuntu session or whatever wsl you have set on your own.
A little bit nooby on this but trying to help. =)
I'm running IntelliJ 2018.3 on Windows 7, as well as openSUSE Leap 15.
Under Windows 7, I've configured IntelliJ to use Git Bash, i.e., in Settings, under Tools -> Terminal, I'm setting Shell path to:
C:\Program Files (x86)\Git_2.17.1\bin\bash.exe
One of IntelliJ's new features is the ability to save and reload terminal sessions (see this link).
It works perfectly with openSUSE, however, on Windows, while the terminal tab names are correctly restored, I always end up with a new shell.
Is there a way to make IntelliJ and Git Bash play well together so that I can retain the current working directory and shell history after restarting IntelliJ?
You can try and setup your Git for Windows bash to remember the last used path for you, as seen in "How can I open a new terminal in the same directory of the last used one from a window manager keybind?"
For instance:
So instead of storing the path at every invocation of cd the last path can be saved at exit.
My ~/.bash_logout is very simple:
echo $PWD >~/.lastdir
And somewhere in my .bashrc I placed this line:
[ -r ~/.lastdir ] && cd $(<~/.lastdir)
That does not depend on Intellij IDEA directly, but on the underlying bash setup (here the Git for Windows bash referenced and used by Intellij IDEA.
Here's a possible workaround. It was heavily inspired by VonC's answer, as well as other answers to the question that he mentioned.
~/.bashrc
if [[ -v __INTELLIJ_COMMAND_HISTFILE__ ]]; then
__INTELLIJ_SESSION_LASTDIR__="$(cygpath -u "${__INTELLIJ_COMMAND_HISTFILE__%history*}lastdir${__INTELLIJ_COMMAND_HISTFILE__##*history}")"
# save path on cd
function cd {
builtin cd $#
pwd > $__INTELLIJ_SESSION_LASTDIR__
}
# restore last saved path
[ -r "$__INTELLIJ_SESSION_LASTDIR__" ] && cd $(<"$__INTELLIJ_SESSION_LASTDIR__")
fi
I don't like the fact that I had to wrap the cd command, however Git Bash does not execute ~/.bash_logout unless I explicitly call exit or logout; unfortunately due to this limitation, the .bash_logout variant is inadequate for the mentioned scenario.
The workaround above also leave small junk files inside __INTELLIJ_COMMAND_HISTFILE__ parent dir, however, I couldn't do any better.
Additionally I've opened a ticket in Jetbrain's issue tracker. There are many different shells that may benefit from official support. It would be great if JetBrains could eventually support powershell and popular terminals like windows-subsystem-for-linux, cygwin and git-bash. The only shell that currently works out of the box for me is cmd.