Published in Articles on by Michiel van Oosterhout ~ 4 min read
In this article we will look at how to configure Bash on Windows. We'll set it up so that Bash included in Cygwin (see Git for Windows revisited), Bash included in Git for Windows (see Installing Git on Windows), and Bash included in a Linux distribution running on WSL (see Windows' Subsystem for Linux) all use the same configuration.

Bash startup files
When a new Bash process starts it will processes certain startup files. Simply stated: an interactive shell will process ~/.bashrc
. An interactive login shell will process ~/.bash_profile
instead.
Interactive shell
An interactive Bash process (interactive shell) is one which reads from and writes to a terminal (for example, Console Window Host or Windows Terminal). Among other things, an interactive shell displays a prompt, enables command line editing, and expands aliases. When the PS1
variable is set the Bash process is likely interactive.
- Bash started from another command-line shell is an interactive shell.
Login shell
A login Bash process (login shell) is one which ensures correct initialization of a login session, such as processing certain startup files that should be processed only once per session. In a Bash login shell the login_shell
option is set. A login shell is typically interactive.
- Git Bash started via the Start menu is an interactive login shell (
git-bash.exe
passes the--login
and-i
options to Bash). - Bash running on WSL started via
bash.exe
,wsl.exe
, ordebian.exe
is an interactive login shell.
Configuring Bash
We'll need to create the .bash_profile
and .bashrc
files.
.bash_profile
First we'll create .bash_profile
, for login shells. This Bash script will source all Bash scripts found in the $USERPROFILE/.config/bash/login.d
directory. This approach ensures we can add new configuration scripts later. After that, the script also sources .bashrc
, so that interactive login shells have the same configuration as interactive non-login shells.
# Ensure the directory exists
$path = "$Env:USERPROFILE\.config\bash\login.d"
$_ = New-Item $path -Force -ItemType Directory
# Declare the Bash script contents
$script = @'
dir=${USERPROFILE//\\//}/.config/bash/login.d
if [ -d $dir ]; then
for file in $dir/*.bash; do
[ -r $file ] && . $file
done
fi
file=${USERPROFILE//\\//}/.bashrc
[ -r $file ] && . $file
'@
# Create the Bash script
$path = "$Env:USERPROFILE\.bash_profile"
Set-Content -Path $path -Value $script
# Ensure proper line endings
((Get-Content $path) -join "`n") + "`n" | Set-Content -NoNewline $path
.bashrc
Next we'll create .bashrc
, for interactive shells. This Bash script will exit if it is not sourced in an interactive shell, and otherwise it will source all Bash scripts found in the $USERPROFILE/.config/bash/interactive.d
directory.
# Ensure the directory exists
$path = "$Env:USERPROFILE\.config\bash\interactive.d"
$_ = New-Item $path -Force -ItemType Directory
# Declare the Bash script contents
$script = @'
[ -z "$PS1" ] && return
dir=${USERPROFILE//\\//}/.config/bash/interactive.d
if [ -d $dir ]; then
for file in $dir/*.bash; do
[ -r $file ] && . $file
done
fi
'@
# Create the Bash script
$path = "$Env:USERPROFILE\.bashrc"
Set-Content -Path $path -Value $script
# Ensure proper line endings
((Get-Content $path) -join "`n") + "`n" | Set-Content -NoNewline $path
WSL
For Bash included in a Linux distribution running on WSL we'll need to do 3 things to ensure it uses the same configuration:
- Add
USERPROFILE
toWSLENV
- Source
$USERPROFILE/.bash_profile
from~/.bash_profile
- Source
$USERPROFILE/.bashrc
from~/.bashrc
# Add USERPROFILE to WSLENV
cmd /c setx WSLENV "%WSLENV%:USERPROFILE/pu"
# Source .bash_profile_
wsl echo "[ -r \`"`$USERPROFILE/.bash_profile\`" ] && . \`"`$USERPROFILE/.bash_profile\`"" `> ~/.bash_profile
# Source .bashrd
wsl echo "[ -r \`"`$USERPROFILE/.bashrc\`" ] && . \`"`$USERPROFILE/.bashrc\`"" `> ~/.bashrc
By using the /pu
option for the USERPROFILE
environment variable, WSL will 'translate' the path to a valid Linux path (e.g. something like /mnt/c/Users/michiel
).
Conclusion
With some relatively simple Bash scripts in specific locations it is possible to have single configuration that works for 3 commonly used Bash implementations: Cygwin, Git for Windows, and WSL.