cygwin linux

Cygwin walkthrough and beginners guide
Linux for Windows or a POSIX-compatible alternative shell?

Learn the purpose of Cygwin and how to install, maintain and use this fantastic tool.

Reading time of 3292 words
16 minutes
Reading time of 3292 words ~ 16 minutes

If you find this content useful, consider buying me a coffee
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 2022 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.

Windows support

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.

Q: How can I install the last Cygwin version for an old, unsupported Windows?

In October 2022, I attempted to use the time machine mirrors for Windows XP and 2000, but neither worked.

Cygwin setup in Windows XP
Setup fails to complete with my use of the time machine mirror


So let’s get started by visiting 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 setup-x86_64.exe!

Cygwin setup
Cygwin Net Release Setup Program
Choose a download source
Select, Install from Internet
Select Root Install Directory
Follow the RECOMMENDED choice

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 C:\Program Files\cygwin64.

Local Package Directory

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.

Select Your Internet Connection
Use System Proxy Settings

Choose A Download Site
Choose a download site from the available list

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.

Selecting packages

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.

Select Packages
The Shells category contains 36 packages

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.

Select Packages
Selecting The Z-Shell gives a few version installation options
Review and confirm changes
Review the packages to install
Download Progress
Download and install the Cygwin packages
Installation Complete
The installation is complete

Once the installation is complete, use the Cygwin desktop icon or the Start menu entry to launch Cygwin64 Terminal.

Cygwin64 Terminal icon on Windows 11
Cygwin64 Terminal item in Start

Cygwin terminal options

Welcome to your Windows-compiled Bash shell. You can test this by running the Bash version.

Welcome to Cygwin
$ 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 <>

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.

Mintty menu
The not so obvious Options of Mintty

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.

Mintty Options
Looks in Terminal options of Mintty

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.

Windows properties

  • Default size for Columns is 100 and Rows is 24.

Terminal features

  • 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: c:\cygwin64\home\Ben\

Cygwin home directory
The home directory of Ben viewed in File explorer
  • .bashrc is our Bash shell configuration.
  • .minttyrc has 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'

Open .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.

My edits to the .bashrc file

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.
Bash shell in color
You now see a colorized directory and file listings

Bash tips

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"
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"
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: C:\cygwin64

In a Cygwin terminal, list the available arguments for the setup program: /setup-x86_64 --help

$ /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 --quiet-mode and --package-manager arguments.

$ /setup-x86_64 --quiet-mode --package-manager

You can also upgrade packages with --quiet-mode and --upgrade-also arguments.

$ /setup-x86_64 --quiet-mode --upgrade-also

Knowing a package’s name means it can be installed from the command line using --quiet-mode and --packages [package names].

And to remove an installed package, you’d use the --quiet-mode and --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

As 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: c:\cygwin64\home\Ben\.bashrc

# 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

$ 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: ~/lighttdpd.conf

$ touch ~/lighttdpd.conf

Create a placeholder world-wide-web directory.

$ mkdir ~/www

Also, print the absolute path of the ~/www using readlink, make a note of the path; for me it is: /home/Ben/www

$ readlink -f ~/www

Insert the following configuration below and save it to: ~/lighttdpd.conf

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.

touch ~/www/index.html

Open the ~/www/index.html file in a text editor and add the following HTML elements.

<!DOCTYPE html>
<html lang="en">
    <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>
    <h1>Hello, from Cygwin</h1>

Test the quickstart configuration; it will return a blank line if everything looks good.

$ /usr/sbin/lighttpd -tt -f ~/lighttpd.conf

Run 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: http://localhost:3000

Chrome browser
Chrome browser with our barebones HTML file

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: Unknown error 112
$ ps --summary
    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 /var/www.

  • Cygwin.bat A Windows batch file that launches Cygwin in your default terminal emulator. You can use it to launch Cygwin in Windows Terminal.
  • Cygwin.ico, Cygwin-Terminal.ico These are standard Windows icons that you can add to a Windows shortcut, a batch file or a Windows Terminal profile.
Windows Terminal profile
A Cygwin profile in Windows Terminal

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: cygdrive/c/

  • proc/ It lets you view various aspects of your system using the cat print command.

Display the host computer CPU details: cat /proc/cpuinfo

Display the Windows memory information: cat /proc/meminfo

Lists the disk mounts within Cygwin: cat /proc/mounts

Display the Cygwin version details: cat /proc/version

Other popular Cygwin packages may be of interest.

Database category

  • mysql* the world’s most popular open source database
  • postgresql a powerful, open source object-relational database
  • sqlite3 a small, fast, SQL database engine

Net category

  • 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

Web category

  • 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

If you find this content useful, consider buying me a coffee
Or help me out by engaging with any advertisers that you find interesting