Or help me out by engaging with any advertisers that you find interesting
Cygwin is a fantastic tool for operating system users who regularly use both Windows and Linux but want the power of a Linux or UNIX shell tools running within Windows.
Linux in Windows?
Since the writing of this article way back in 2011, a few things have changed with the Windows and Linux landscape.
After the release of Windows 10 and the company’s tilt toward Azure, Microsoft embraced Linux. Both its use on the cloud and desktop products like Windows. The pragmatic changes included the development of Microsoft Terminal, a much-needed terminal program that is ANSI compatible and Linux / UNIX friendly. And the release of WSL and WSL2, Windows Subsystem for Linux.
Despite these changes within the Windows platform and these first-party Linux tools from Microsoft, Cygwin still has a place in 2023 and beyond.
Cygwin vs WSL vs WSL2?
Cygwin was first conceived in 1995, making it not much younger than the Linux kernel itself. It’s easy to assume that WSL and WSL2 are direct replacement upgrades for this technology. And the same goes for WSL2 over WSL, but the three are functionally very different with various pros and cons.
WSL2 is a preconfigured, lightweight utility virtual machine that runs an actual Linux kernel. It offers integration between Linux and Windows and a choice of common Linux distributions.
WSL was initially called Bash on Windows, and its functionality reflects that name. Instead of using a virtual machine to run a Linux kernel, WSL intercepts the commands of a Linux shell program and translates them on the fly to work with the Windows kernel. This method offers less compatibility than virtualization.
Cygwin is a compatibility layer for Windows that shares a standard API with various other operating systems, including Linux, macOS and UNIX. Programs written for this POSIX compatibility can compile and run regardless of the original platform allowing many open-source tools from Linux and UNIX to run natively on Windows.
POSIX is the portable operating system interface for UNIX, and it is not a coincidence that Cygwin was once marketed as a free Windows porting layer for UNIX.
- So applications ported to Cygwin run natively in Windows.
- But the same application running in WSL2, is a Linux program in a virtualized Linux operating system hosted on Windows.
- While WSL runs Linux-compiled programs on Windows but tricks them into thinking they are running on Linux.
These days Cygwin requires a modern 64-bit Windows operating system such as Windows 10 or 11. But back in the day, Cygwin had extensive Windows support going back to Windows 95!
Unfortunately, legacy platforms have been dropped over the years, but community archives host some of the needed distribution packages and setup programs. While Windows 95 users are out of luck, Vista, XP, and 2000 still have mirrors online thanks to the Cygwin Time Machine.
In October 2022, I attempted to use the time machine mirrors for Windows XP and 2000, but neither worked.
So let’s get started by visiting https://cygwin.com/install.html. Download, then run the
setup-x86_64.exe package manager for Cygwin. By default, it will download and install the latest minimal install of Cygwin. Future launches will enable you to add new packages and update your existing Cygwin software. So after you install Cygwin, do not delete or lose the location of
By default, Cygwin will install to
C:\cygwin64, but you can change this to any directory you choose. I advise not to select a directory path containing spaces in the name so avoid
Cygwin setup will save all downloaded packages to the Local Package Directory after it has finished the installation. You can either delete them, leave them or back them up elsewhere for future use on this or other computers.
Choose A Download Site lets you select an online repository from where Cygwin setup will download the packages and files. It is preferable to pick a location for a site that is physically closer to you. But if you can not determine this from the country codes in the site names or cannot find a suitable mirror, then select the first item.
The Select Packages screen is the most critical part of the Cygwin setup as it acts as the Cygwin package manager interface, equivalent to the Synaptic Package Manager in Debian Linux.
The rest of this section covers the interface features of the package manager, but as a first-time user of Cygwin, you can completely ignore all of these and press Next to accept the default installation.
The Search input lets you quickly filter packages by name. Unfortunately, the search does not work on the package descriptions.
The Keep, Best and Sync radio selections let you apply installation restrictions on all packages.
- Keep forces Cygwin setup to leave all installed packages as they are to ignore any available updates.
- Best is the default recommended option and lets Cygwin choose the most appropriate versions of packages and libraries.
- Sync keeps all packages and libraries synchronized with those on the package repository, which could overwrite any external updates you apply.
The Package table column contains categories of software and libraries, which are expandable to reveal individual packages. I have the Shells category on the screen above, showing 36 packages.
The Current table column lists the installed package or library version value. On the first time install of Cygwin, these will remain empty.
The New table column lets you select a specific package version for installation, downgrade, or removal. You can also use the column to install or remove a whole category of packages.
- Default keeps the packages within the categories as-is.
- Install selects all the packages within the category for installation.
- Reinstall will overwrite any existing packages with a fresh installation using the same version value.
- Uninstall removes any installed packages from the category.
- Skip ignores the package listed in the repository.
- Uninstall removes the installed package from the Cygwin system.
The Src? table column lets you check a box to download the package’s source code to your Cygwin installation.
The Size table column is the package download size in Kilobytes.
The Description table column contains the package name and a brief description.
Once the installation is complete, use the Cygwin desktop icon or the Start menu entry to launch Cygwin64 Terminal.
Cygwin terminal options
Welcome to your Windows-compiled Bash shell. You can test this by running the Bash version.
$ bash --version GNU bash, version 4.4.12(3)-release (x86_64-unknown-cygwin) Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
Cygwin uses the Mintty terminal emulator out of the box, a competent tool though its default configuration is a bit old-fashioned. Mintty is configurable using the Options… item found by clicking the Cygwin logo of the app.
Within the Options of Mintty under Looks in Terminal, you can change the transparency, cursor, or color theme. Under Text and Font properties, you can change the font, smoothing, boldness, locale, character set, and emoji support. The Window properties allow for the default size and scrollback cache. In comparison, Terminal features will enable you to adjust to the terminal type, bell, and printer.
Here are my Mintty customized options.
Looks in Terminal
- Cursor is set to Underscore.
Text and Font properties
- Font is Cascadia Mono at Size 10.
- I set Show bold as font & as colour and Allow blinking.
- Default size for Columns is 100 and Rows is 24.
- The Bell is set to no beep, but Flash and Highlight in taskbar are checked.
Bash shell options
The first thing I recommend is customizing your Bash shell to implement some aliases for basic coloring on a few staple Cygwin commands.
List all the files in your home directory on Cygwin:
ls -A ~
$ ls -A ~ .bash_history .bash_profile .bashrc .inputrc .minttyrc .profile
You can access and view this same directory in Windows File explorer. For my installation, the home directory on Cygwin is at:
.bashrcis our Bash shell configuration.
.minttyrchas the configuration for the Mintty terminal emulator.
- The other files are for backward compatibility with various shell configurations and can be ignored.
Make a backup of the original Bash shell configuration file:
cp .bashrc .bashrc_orginal
$ cp -v .bashrc .bashrc_orginal '.bashrc' -> '.bashrc_orginal'
.bashrc with a text editor such as Notepad or Notepad++. At the end of the heavily commented (
#) file, append any Bash settings you feel appropriate.
This setting disables the use of Ctrl+D to quit Mintty.
# Don't use ^D to exit set -o ignoreeof
As Cygwin has full access to the Windows file system (
/cygdrive/c), you may wish to always confirm the use of remove, copy and move commands.
# Interactive operation... alias rm='rm -i' alias cp='cp -i' alias mv='mv -i'
Use human readable sizes with disk-free and disk-usage commands.
# Default to human readable figures alias df='df -h' alias du='du -h'
These directory-listing aliases are pretty commonplace.
# Some shortcuts for different directory listings alias ls='ls -hF --color=tty' # classify files in colour alias dir='ls --color=auto --format=vertical' alias vdir='ls --color=auto --format=long' alias ll='ls -l' # long list alias la='ls -A' # all but . and .. alias l='ls -CF' #
When done, save any changes to
.bashrc and use the
source command to apply the new configuration to Bash. Afterward, you should be able to test out any new aliases or changes.
$ source ~/.bashrc $ df Filesystem Size Used Avail Use% Mounted on C:/cygwin64 931G 634G 298G 69% / $ la .bash_history .bash_profile* .bashrc* .bashrc_orginal* .inputrc* .minttyrc .profile* $ Use "logout" to leave the shell.
Tapping Ctrl+L will clear the terminal screen.
Tapping Ctrl+D will exit the shell session and most probably quit Mintty.
You can use Tab to (auto)complete commands, arguments, filenames, and directories automatically. This Bash feature is superior to the simpler competition used by PowerShell.
You can chain two or more commands using a semicolumn
; character or two ampersands
&& as the separator. Using ampersands will abort the chain whenever errors occur, while the semicolumns will run the whole chain regardless.
# semicolumn chain $ echo "Hello"; echo "End of the chain" Hello End of the chain # the semicolumn chain always continues after an error $ ech "Hello"; echo "End of the chain" -bash: ech: command not found End of the chain # ampersands chain $ echo "Hello" && echo "End of the chain" Hello End of the chain # the ampersands chain always stops at an error $ ech "Hello" && echo "End of the chain" -bash: ech: command not found
Package management and updates
Besides the downloaded installer
setup-x86_64.exe, Cygwin has no apparent means to update or install new packages and libraries. Fortunately,
setup-x86_64.exe has a collection of command line arguments that we can use within a terminal to simplify and manage packages.
First, place the
setup-x86_64.exe into the Cygwin root directory, or you can redownload it and save it there instead. On my setup, the root directory is at:
In a Cygwin terminal, list the available arguments for the setup program:
$ /setup-x86_64 --help Cygwin setup 2.919 Command Line Options: -t --allow-test-packages Consider package versions marked test --allow-unsupported-windows Allow old, unsupported Windows versions...
If you run setup from the terminal without any arguments, it launches the Cygwin setup program from the start asking the unnecessary installation and download location questions. But these can be skipped using the
$ /setup-x86_64 --quiet-mode --package-manager
You can also upgrade packages with
$ /setup-x86_64 --quiet-mode --upgrade-also
Knowing a package’s name means it can be installed from the command line using
--packages [package names].
And to remove an installed package, you’d use the
--remove-packages [package names], as shown in the example.
# install Wget from the terminal $ /setup-x86_64 --quiet-mode --packages wget # test Wget $ wget --version GNU Wget 1.21.3 built on cygwin. # remove Wget from the terminal $ /setup-x86_64 --quiet-mode --remove-packages wget # Wget has been removed $ wget --version -bash: /usr/bin/wget: No such file or directory
Multiple packages can be listed using a comma separator.
# batch install $ /setup-x86_64 --quiet-mode --packages wget,nano # batch uninstall $ /setup-x86_64 --quiet-mode --remove-packages wget,nano
setup-x86_64 is somewhat annoying to memorize and type, as are its arguments, let’s use the alias feature of Bash to create some memorable shortcuts instead. Edit the
.bashrc config file in the home directory and append the following aliases. For my installation, the
.bashrc file is at:
# install packages alias install='/setup-x86_64 --quiet-mode --packages' # remove packages alias uninstall='/setup-x86_64 --quiet-mode --remove-packages' # list packages alias list='/setup-x86_64 --quiet-mode' # run setup alias setup='/setup-x86_64' # upgrade packages alias upgrade='/setup-x86_64 --quiet-mode --upgrade-also' # display cygwin version alias ver='/setup-x86_64 --version'
When complete, save
.bashrc and refresh Bash to use the changes:
$ source ~/.bashrc $ ver Cygwin setup 2.919 $ upgrade $ install wget,nano $ uninstall wget,nano
Services and daemons
Want to implement a daemon (a Windows service) with your Cygwin install? Here is a simple example using lighttpd, a lightweight HTTP server. Using the Cygwin terminal, install
lighttpd either with the alias or the full setup command.
# use the alias $ install lighttpd # or the setup command $ /setup-x86_64 --quiet-mode --packages lighttpd
Once installed, lighttpd is found at
/usr/sbin/lighttpd.exe and is runnable from the terminal.
$ whereis lighttpd lighttpd: /usr/sbin/lighttpd.exe /usr/lib/lighttpd /etc/lighttpd /usr/share/man/man8/lighttpd.8.gz $ /usr/sbin/lighttpd -v lighttpd/1.4.67 (ssl) - a light and fast webserver
Create a placeholder configuration file in the home directory and save it to:
$ touch ~/lighttdpd.conf
Create a placeholder world-wide-web directory.
$ mkdir ~/www
Also, print the absolute path of the
readlink, make a note of the path; for me it is:
$ readlink -f ~/www /home/Ben/www
Insert the following configuration below and save it to:
But make sure the path of
server.document-root reflects the absolute
~/www path in your home.
server.document-root = "/home/Ben/www/" server.port = 3000 server.username = "www" server.groupname = "www" mimetype.assign = ( ".html" => "text/html", ".txt" => "text/plain", ".jpg" => "image/jpeg", ".png" => "image/png" ) static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc" ) index-file.names = ( "index.html" )
Create an index HTML file in
~/www/index.html file in a text editor and add the following HTML elements.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Hello, from Cygwin</title> </head> <body> <h1>Hello, from Cygwin</h1> </body> </html>
Test the quickstart configuration; it will return a blank line if everything looks good.
$ /usr/sbin/lighttpd -tt -f ~/lighttpd.conf
lighttpd with the quickstart configuration. Later, you can use
Ctrl+C to exit.
$ /usr/sbin/lighttpd -D -f ~/lighttpd.conf 2022-10-11 14:35:47: (/home/gps/src/gstrauss/cygport/cygport-lighttpd/lighttpd-1.4.67-1.x86_64/src/lighttpd-1.4.67/src/server.c.1588) server started (lighttpd/1.4.67)
Once running, point your browser to:
To run lighttpd in the background, remove the
-D argument as so:
/usr/sbin/lighttpd -f ~/lighttpd.conf
$ /usr/sbin/lighttpd -f ~/lighttpd.conf
lighttpd offers the
-i argument to shut down the server gracefully, but it may not always work. You can use the
ps command to list and
kill to stop the process when this happens.
$ /usr/sbin/lighttpd -i 8 -f ~/lighttpd.conf 2022-10-12 12:36:59: (/home/gps/src/gstrauss/cygport/cygport-lighttpd/lighttpd-1.4.67-1.x86_64/src/lighttpd-1.4.67/src/network.c.540) can't bind to socket: 0.0.0.0:3000: Unknown error 112
$ ps --summary PID TTY STIME COMMAND 322 pty0 12:25:35 /usr/bin/bash 320 ? 12:07:00 /usr/sbin/lighttpd 352 pty0 12:37:37 /usr/bin/ps 291 cons0 10:45:14 /usr/bin/bash 321 ? 12:25:35 /usr/bin/mintty $ kill 320
Congratulations! You have successfully implemented a Bash shell environment on your Windows operating system that also has a robust but simple HTTP server.
More information on Cygwin is found in its User’s Guide.
Appendix: A drill-down of the Cygwin root directory
$ la / Cygwin-Terminal.ico Cygwin.ico cygdrive/ etc/ lib/ sbin/ tmp/ var/ Cygwin.bat* bin/ dev/ home/ proc/ setup-x86_64.exe* usr/
bin/It is a directory containing essentual user programs compiled for Windows under Cygwin. Included are many unique POSIX-compatible commands and applications that give you extra terminal functionality that a bare-Windows install often lacks.
dev/It is short for devices or device files. Originally for POSIX, this is where your detected hardware devices are listed, but in Cygwin, its usage is mainly for software compatibility.
etc/It contains most of the Cygwin-related configuration files. Unlike the Windows registry, these should be editable plain text files and modifiable by any text editor.
home/It contains user directories similar to the Windows Users directories. It is where files unrelated to Cygwin, such as your documents and file downloads, should be stored.
lib/This ignorable directory is an abbreviation for libraries. Various Cygwin commands and applications use these shared components.
sbin/It is short for system binaries and usually contains programs essential for the operating system.
tmp/It is the directory for use by Cygwin and any other programs for temporary files. Anything found or placed here is liable for deletion.
usr/It is a somewhat confusing directory that people often call the user or short for the UNIX system resources. There are many user-usable programs and their operational assets, such as libraries, source code, etc.
var/It is where variable data files are stored. These are files generated by your applications. For example, log files would go in
/var/log. If you run an HTTP server, the files it hosts maybe be found at
Cygwin.batA Windows batch file that launches Cygwin in your default terminal emulator. You can use it to launch Cygwin in Windows Terminal.
Cygwin-Terminal.icoThese are standard Windows icons that you can add to a Windows shortcut, a batch file or a Windows Terminal profile.
These virtual directories are visible in the Cygwin terminal but not in Windows File Explorer.
cygdrive/It contains a list of mounted Windows drive letters. From here, you can access any Windows drive partition. For example, this points to the Windows C: drive:
proc/It lets you view various aspects of your system using the
Display the host computer CPU details:
Display the Windows memory information:
Lists the disk mounts within Cygwin:
Display the Cygwin version details:
Appendix: Popular Cygwin applications
Other popular Cygwin packages may be of interest.
- mysql* the world’s most popular open source database
- postgresql a powerful, open source object-relational database
- sqlite3 a small, fast, SQL database engine
- ctorrent BitTorrent client
- lftp a sophisticated file transfer program
- ncftp a powerful FTP client
- openssh the premier connectivity tool for remote login
- pure-ftpd a secure FTP daemon
- rsync gives fast incremental file transfer
Programming languages as categories
- lighttpd a secure, fast, compliant, and very flexible web server
- httpd* Apache HTTP server project
- nginx* NGINX HTTP and reverse proxy server
- wget retrieve files using HTTP, HTTPS, FTP and FTPS
* When checked in October 2022, these packages in Cygwin were unmaintained.
Written by Ben Garrett