[26 Sep 2023]
Copy-paste the commands below, do NOT type them!
Setting up WSL
Microsoft has developed a way to run Linux and Linux-based applications
natively under Windows, through WSL (Windows Subsystem for Linux), a
feature of the Windows operating system. At the time of writing this
(Sep 2023), one first must do the following:
-
Enable WSL (instructions taken from https://learn.microsoft.com/en-us/windows/wsl/install):
Open a Windows terminal (cmd.exe or powershell) AS AN
ADMINISTRATOR.
On the terminal run:
wsl –install
-
Once the installation has finished, set up your username and password.
For the whole story, have a look here: https://learn.microsoft.com/en-us/windows/wsl/setup/environment
In short – your username is something that refers to you, like
"abcd123" at City. It could be your name. It MUST NOT CONTAIN A SPACE
– only letters and numbers. Keep it short, better to use "tim"
than "timothy".
Your password – make sure you don't forget it, you'll need it to
update the Linux system and its applications.
-
Reboot Windows.
-
Now you should have a new application "Ubuntu" – running it should cause a Linux terminal to
appear.
-
(Inside the Linux terminal) Update the Linux apps and install a few more:
-
Update the lists of apps – run:
sudo apt update
Did this command fail?
(sudo asks for your Linux password)
Do you get that some servers are unreachable?
If so, run (and see below for a long-term solution to this):
echo nameserver 8.8.8.8 > ~/resolv.conf
sudo cp -p ~/resolv.conf /etc/
Now, try the command (sudo apt update) again – it should work fine.
-
Upgrade current applications:
sudo apt -y upgrade
-
Install a number of development applications (copy-paste till the build-essential!):
sudo apt -y install default-jdk \
gcc gdb make \
x11-apps rxvt-unicode emacs \
g++ tcl tk graphviz clang \
automake autoconf build-essential \
tkcvs unzip dos2unix zip
-
Use the commands in the previous section to install brew & gcc from brew (brew's gcc is a more recent version)
You're good to go! 😁 😁 😁
Networking Issues – Unreachable servers
If your first attempt at apt update failed due to network issues, it could be that the nameserver used to resolve server names by default is not working. The solution in 5)a works but it only works for the current session. This is because the standard WSL configuration auto-generates file /etc/resolv.conf (which contains the nameserver to use) each time WSL starts. We need to disable this behaviour in file /etc/wsl.conf
So, first make a copy of /etc/wsl.conf:
cp -p /etc/wsl.conf ~/wsl.conf-original
cp /etc/wsl.conf ~/wsl.conf.txt
(cd ~ ; explorer.exe wsl.conf.txt)
The previous command should open notepad on the contents of wsl.conf.txt – now add the following into this file:
[network]
generateResolvConf = false
To give you a better idea, my wsl.conf contains:
[boot]
systemd=true
[network]
generateResolvConf = false
The new addition tells WSL to not generate file /etc/resolv.conf each
time it starts.
Save file on Notepad and close Notepad. Now, copy back your local
wsl.conf.txt into the system configuration:
sudo cp -p ~/wsl.conf.txt /etc/wsl.conf
Now exit from the terminal (type the command exit).
Start Ubuntu again. File /etc/resolv.conf shouldn't exist at all now
(WSL deleted its auto-generated version when it terminated):
ls /etc/resolv.conf
So, let's create our own that uses Google's nameserver (8.8.8.8), just
like we did before (only this time our file will stay there for ever):
echo nameserver 8.8.8.8 > ~/resolv.conf
sudo cp ~/resolv.conf /etc/
We're done!
😁 😁 😁
Linux editors
There are two standard editors on Unix: vi and emacs. Emacs is more
powerful and easier to start with – vi is guaranteed to exist always
(so you need to learn it).
File paths: Windows 2 Linux 2 Windows
File/folder names that contain spaces will not work on Linux - spaces and
other special characters [$!'"`] need to be escaped with a backslash "\"
(not a slash "/" - that's used in Linux to separate folders).
Your C: drive should be accessible at /mnt/c/ from Linux under WSL. Your
Linux files should be accessible under \\wsl.localhost\ from Windows
File Explorer (you'll need something like \\wsl.localhost\Ubuntu from
inside PowerShell).
If you have OneDrive/GDrive/etc it should be under
/mnt/c/Users/XXX/OneDrive..., where XXX is your Windows user name.
You want to find out how to access a Windows path/file from Linux? Use
wslpath:
wslpath "c:\Users"
(result: /mnt/c/Users)
You want to find our how to access a Linux file
from Windows? Use wslpath -w:
wslpath -w /etc/wsl.conf
(result: \\wsl.localhost\Ubuntu\etc\wsl.conf)
You can use File Explorer to open files from the
terminal, like we did above for wsl.conf.txt:
(cd ~ ; explorer.exe wsl.conf.txt)
Why did I write all that instead of "explorer.exe wsl.conf.txt"?
Because I don't know which directory (directory=folder) your terminal
is currently at. Explorer can open files that are visible in the current
directory only. So, the command above started a new child shell (that's
the surrounding parentheses), then changed the current directory in that
shell to be your home directory (that's "cd ~" – the tilde character
"~" is an alias for your home directory), and only then called Explorer
on the file.
Try changing your directory to /tmp and then running
explorer on the file above to see that it doesn't work, because the file
is not in your current directory:
cd /tmp; explorer.exe wsl.conf.txt
The following doesn't work either, because Explorer doesn't understand Linux paths:
explorer.exe ~/wsl.conf.txt
Super-quick introduction to quoting in Linux
The following would have worked too from anywhere
(note that the quotes are backquotes, not single quotes!):
explorer.exe `wslpath -w ~/wsl.conf.txt`
The backquotes ask the shell to execute that part of the command
first and replace it with its outcome before executing the whole command.
NOTE: There are three kinds of quotes:
- Single quote (or just quote)
- ' whatever inside single quotes is used as is.
- Double quote
- " things inside double quotes are evaluated (e.g., shell variable names are replaced by their values)
- Backquote
- ` quoted string is assumed to be a command to execute and then use its result
Compare:
echo echo '${USER}'
echo echo "${USER}"
echo `echo "${USER}"`
Graphical Linux applications
Try to run xeyes – do you get the eyes displayed? If not, https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps
The road to enlightenment - take...
MIT's "The Missing Semester of Your CS Education"
https://missing.csail.mit.edu/