# Cygwin setup on *Windows* [Cygwin](https://www.cygwin.com) is a Unix-Emulator that provides a terminal ([mintty](https://mintty.en.lo4d.com/windows)) in which Unix commands can be executed on Windows using *[bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell))* (*Bourne Again Shell*) as command-line interpreter. *bash* was developed in 1989 as a successor to the *Bourne Shell* *[sh](https://en.wikipedia.org/wiki/Bourne_shell)*. Example of a [bash terminal](https://cdn.ttgtmedia.com/rms/onlineimages/REF_bash_command_line_3.jpg). *Cygwin* is <span style="text-decoration:underline">not</span> a Unix system, container or virtual machine (like [WSL](https://learn.microsoft.com/en-us/windows/wsl/about)). *Cygwin* emulates most (but not all) Unix system calls such that most Unix commands can be used on Windows. [GitBash](https://gitforwindows.org) is an alternative to *Cygwin* that uses a different emulator package [MinGW](https://www.mingw-w64.org). It has has some flaws, for example, it performs path conversions that may cause problems, see [link](https://stackoverflow.com/questions/54258996/git-bash-string-parameter-with-at-start-is-being-expanded-to-a-file-path). Read [Differences between Cygwin and MinGW](https://stackoverflow.com/questions/771756/what-is-the-difference-between-cygwin-and-mingw) for more detail about the differences between *Cygwin* and *MinGW / GitBash*. Good introductions to *bash* are: - [https://cs.lmu.edu/~ray/notes/bash](https://cs.lmu.edu/~ray/notes/bash). - Also recommended is the [Tutorial for Beginners](https://linuxconfig.org/bash-scripting-tutorial-for-beginners). ## Steps 1. [Install *Cygwin*](#1-install-cygwin) 2. [Configure *Cygwin* and *bash*](#2-configure-cygwin) - switch from `/cygdrive/c` to `/c` - select HOME-directory - configure *.bashrc* in HOME-directory - define PATH in *.bashrc* 3. [Customize *bash*](#3-customize-bash) 4. [References](#4-references) ## 1. Install Cygwin 1. Download the installer `setup-x86_64.exe` from [https://www.cygwin.com/install.html](https://www.cygwin.com/install.html). 1. Run the installer `setup-x86_64.exe`. - select useful Unix commands during installation: - Editors/`vim` - visual editor, - Web/`wget` - web downloader, - Net/`curl` - web downloader. 1. Change *cygwin* default path `/cygdrive/c` to: `/c`: - navigate to the *cygwin* installation directory called `cygwin64`. - inside, edit `/etc/fstab` and replace line ``` none /cygdrive cygdrive binary,posix=0,user 0 0 with: none / cygdrive binary,posix=0,user 0 0 ``` 1. Add bash-user that works with Windows and create *bash* HOME directory. - Find out your Windows user name: <user_name> - Create or select a directory to use as HOME-directory for *bash*, e.g. your Windows HOME-directory `C:\Users\<user_name>` (but also any other directory you may create as HOME). Read [Change Cygwin home folder after installation](https://stackoverflow.com/questions/1494658/how-can-i-change-my-cygwin-home-folder-after-installation). - Edit file `/etc/nsswitch.conf`: - to use your Windows HOME-directory, comment line (put hash # in front) ``` #db_home: ``` - to use a different HOME directory `<path>`, enter ```sh db_home: /c/<path> # e.g. db_home: /c/users/svgr ``` 1. Create a terminal icon on your Desktop. - In the installation directory (`cygwin64`), navigate to `./bin` and find file [mintty.exe](https://en.wikipedia.org/wiki/Mintty), which is the terminal emulator executable. - Create a shortcut for *mintty.exe* (right-click file -> Create Shortcut -> On Desktop). The terminal icon appears on your desktop. 1. Open *mintty* terminal and test: ```sh $ whoami <user_name> # your user name appears $ echo $HOME # print path to HOME-directory <home_directory> # output, e.g. /c/Users/svgr $ cd $HOME # change into HOME-directory $ ls -la # show content total 203 drwxr-xr-x+ 1 svgr2 Kein 0 Oct 4 22:20 . drwxrwx---+ 1 svgr2 Kein 0 Jan 1 2022 .. -rw------- 1 svgr2 Kein 14476 Oct 4 22:20 .bash_history -rwxr-xr-x+ 1 svgr2 Kein 2717 Oct 4 20:28 .bashrc ... $ echo Hello >hello.txt # create file hello.txt with content Hello $ ls -la # show new file exists in $HOME total 203 -rw-r--r-- 1 svgr2 Kein 6 Oct 7 23:38 hello.txt ... $ cat hello.txt # output content of file Hello ``` 1. Open Windows file explorer ( [ ? ](https://geekflare.com/wp-content/uploads/2021/06/14-alternative-file-managers-to-replace-windows-10-file-explorer.jpg) ) and navigate to file `hello.txt`. Open the file by clicking (ending `.txt` should open the file with *notepad*). 1. Return to *bash* terminal: - change to HOME-directory and - show content of file `.bashrc` using a text editor: *[vim](https://www.vim.org)* (already installed with cygwin), *[nano](https://www.nano-editor.org)* or *[sublime](https://www.sublimetext.com)* are good choices. ```sh $ cd # change to bash HOME-directory $ ls -la # find file .bashrc total 203 -rwxr-xr-x+ 1 svgr2 Kein 2717 Oct 4 20:28 .bashrc $ cat .bashrc # output file .bashrc content of file .bashrc appears... ``` ## 2. Configure *Cygwin* [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) is an environment variable on Unix-like operating systems that specifys a set of directories where executable programs are located. A *"command not found"* error occurs when PATH is not properly configured. 1. Inspect the current PATH variable on your system: ```sh echo $PATH .:/usr/bin:/usr/local/bin:/c/WINDOWS:/c/WINDOWS/system32: ... ``` PATH has a list of directory paths starting from the root directory '/' separated by colon ( : ). To print PATH more readable, replace ( : ) by newlines: ```sh echo $PATH | tr ':' '\n' . /usr/bin /usr/local/bin /c/WINDOWS /c/WINDOWS/system32 ... ``` Make sure these paths are included in PATH. 1. Open `.bashrc` using a text editor (*[sublime](https://www.sublimetext.com)* or *[vim](https://www.vim.org)* - already installed with *cygwin* - are good choices). Append lines for PATH configurations at the end. ```sh $ vim .bashrc # open file .bashrc in vim editor ``` or drag file from file explorer into sublime for editing. 1. Append following PATH configurations at the end of the file - only those relevant on your system adjusted for your system: ```sh # add Windows system paths export PATH=".:/usr/bin:/usr/local/bin" export PATH="${PATH}:$(cygpath ${SYSTEMROOT}):$(cygpath ${SYSTEMROOT})/system32" # if Java, add Java path (as first entry on PATH) # make sure the path to Java exists on your system and is the path # to a JDK (Java Development Kit) and not JRE, which is just the # Java Runtime that has no compiler, no javadoc or jar. export JAVA_HOME="/c/Program Files/Java/jdk-21" export PATH="${JAVA_HOME}/bin:${PATH}" # if Python, add Python path export PYTHON_HOME="/c/Users/svgr2/AppData/Local/Programs/Python/Python312" export PATH="${PATH}:${PYTHON_HOME}" export PATH="${PATH}:${PYTHON_HOME}/Scripts" # if Docker, add Docker path export DOCKER_HOME="/c/Program Files/Docker/Docker" export PATH="${PATH}:${DOCKER_HOME}/resources/bin" ... ``` 1. Verify paths have been added to *PATH* variable: ```sh $ source .bashrc # reload .bashrc to activate PATH definitions $ echo ${PATH} # show PATH .:/usr/bin:/usr/local/bin:/c/WINDOWS:/c/WINDOWS/system32:/c/Program ... $ echo ${$PATH} | tr ':' '\n' # pretty print PATH . /c/Program Files/Java/jdk-21/bin <-- path to JDK executables /usr/bin /usr/local/bin /c/WINDOWS /c/WINDOWS/system32 ... ``` Paths may vary based on your system. 1. Start programs to verify paths have properly been set. ```sh $ java --version java 21 2023-09-19 LTS Java(TM) SE Runtime Environment (build 21+35-LTS-2513) Java HotSpot(TM) 64-Bit Server VM (build 21+35-LTS-2513, mixed mode, sharing) $ python --version Python 3.12.0 $ docker --version Docker version 24.0.6, build ed223bc ``` ## 3. Customize *bash* *bash* is widely customizable, usually by settings in *.bashrc*. - [Bash Prompt customization](https://wiki.archlinux.org/title/Bash/Prompt_customization) - [How to Change Colors on LS in Bash](https://linuxhint.com/ls_colors_bash) - [How to Customize and Colorize the Bash Prompt](https://www.howtogeek.com/307701/how-to-customize-and-colorize-your-bash-prompt/) Skip when no customization is desired. ## 4. References - [What is PATH?](https://en.wikipedia.org/wiki/PATH_(variable)) - Bash tutorials: - [https://cs.lmu.edu/~ray/notes/bash](https://cs.lmu.edu/~ray/notes/bash). - [Tutorial for Beginners](https://linuxconfig.org/bash-scripting-tutorial-for-beginners). - [Differences between Cygwin and MinGW](https://stackoverflow.com/questions/771756/what-is-the-difference-between-cygwin-and-mingw) - [Change Cygwin home folder after installation](https://stackoverflow.com/questions/1494658/how-can-i-change-my-cygwin-home-folder-after-installation).