Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/archenoth/wslsetup

How I like to set up WSL
https://github.com/archenoth/wslsetup

org-mode-notes wsl

Last synced: about 2 months ago
JSON representation

How I like to set up WSL

Awesome Lists containing this project

README

        

#+TITLE:Windows 10 WSL setup
#+AUTHOR:Archenoth
#+EMAIL:[email protected]
:SETTINGS:
#+STARTUP: hidestars inlineimages
#+DRAWERS: SETTINGS
:END:

WSL is nice on its own, but I've found a few ways to make it integrate with Windows a lot nicer!
So this is what I do when I set up WSL!

* Symlinks
The first thing I do when I set up a new WSL instance is make a few symlinks between the two systems.

The first one is for the root drive (Requires root):
#+begin_src sh :dir /sudo:root@localhost:/
ln -s /mnt/c /host
#+end_src

Then I add a few folders in my home folder that make the link between Windows and Linux pretty seamless. (If you already have these folders, you might need to move or nuke them first)

If you aren't running this from Emacs, you can hit =[Windows] + [R]=, type "=%userprofile%=" and hit =[Enter]=. Then hit =[Ctrl] + [L]= type "=bash=" and =[Enter]= again.
This should put you in correct folder this should be run from.
#+begin_src sh :dir (string-trim (shell-command-to-string "wslpath `cmd.exe /c 'echo %USERPROFILE%'`"))
for i in Desktop Documents Downloads Videos Music Pictures; do
ln -s $i ~
done

mkdir ~/Documents/Code ~/Documents/Writing
ln -s ~/Documents/Code ~/Documents/Writing ~
#+end_src

* Base programs
After installing [[https://chocolatey.org/][Chocolatey]], installing some essential programs can be done from the following in an /elevated/ command prompt.
#+begin_src bat :tangle ~/Desktop/install-essentials.bat
choco install xming autohotkey wsltty -y
#+end_src

And after that's done, the wsltty terminal can be set up with the following:
#+begin_src sh :shcmd "cmd.exe"
C:\ProgramData\Chocolatey\lib\wsltty\tools\wslttyinstall\install.bat
#+end_src

My configuration for wsltty is basically just to make it look like a simple and slightly transparent terminal:
[[./mintty.png]]

This goes in =%APPDATA%\wsltty\config=
#+begin_src conf :tangle (string-trim (shell-command-to-string "wslpath `cmd.exe /c 'echo %APPDATA%/wsltty/config'`"))
ThemeFile=dainty-monokai-night-mod
Transparency=5
OpaqueWhenFocused=no
CursorType=block
Font=Consolas
FontHeight=11
ZoomShortcuts=no
AltFnShortcuts=no
BackgroundColour=0,0,0
#+end_src

The above theme is follows, and goes in =%APPDATA%\wsltty\themes\dainty-monokai-night-mod= (Originally from [[https://github.com/alexanderte/dainty-wsltty][here]], and modified slightly for contrast):
#+begin_src conf :tangle (string-trim (shell-command-to-string "wslpath `cmd.exe /c 'echo %APPDATA%/wsltty/themes/dainty-monokai-night-mod'`"))
# source: https://github.com/alexanderte/dainty-wsltty
# MIT License

BackgroundColour=40, 40, 40
Black=51, 51, 51
Blue=106, 126, 200
BoldBlack=102, 102, 102
BoldBlue=129, 154, 255
BoldCyan=102, 217, 239
BoldGreen=166, 226, 46
BoldMagenta=195, 159, 255
BoldRed=249, 38, 114
BoldWhite=248, 248, 242
BoldYellow=226, 226, 46
CursorColour=248, 248, 240
Cyan=86, 173, 188
ForegroundColour=222, 222, 222
Green=134, 180, 43
Magenta=195, 159, 255
Red=196, 38, 94
White=227, 227, 221
Yellow=179, 180, 43
#+end_src

For XMing, I update my [[~/.Xresources][.Xresources]] file to get a slightly nicer looking X11:
#+begin_src conf :tangle ~/.Xresources
Xft.antialias: 1
Xft.dpi: 96
Xft.hinting: 1
Xft.hintstyle: hintsfull
Xft.lcdfilter: lcddefault
Xft.rgba: rgb
#+end_src

Then I edit my [[~/.profile]] to include things like the following at the end:
#+begin_src sh
# Allow graphical Linux programs to know how to connect to XMing
export DISPLAY=127.0.0.1:0

# Make XMing look nicer
xrdb -merge $HOME/.Xresources
#+end_src

For AutoHotKey, I make a little script to start wsltty when I hit =Ctrl + Alt + T=, just like the default keybinding in a lot of Linux window managers.
#+begin_src ahk :tangle ~/Code/ahk/terminal.ahk
^!t::
Run, C:\Users\Archenoth\AppData\Local\wsltty\bin\mintty.exe --WSL= --configdir="%APPDATA%\wsltty" -~
Return
#+end_src

I also make a little vbscript file to run XMing, and then to start bash once (to run my .profile with the Linux-side XMing configuration):
#+begin_src vbscript :tangle ~/Code/vbs/start-xming-profile.vbs
CreateObject("Wscript.Shell").Run """C:\Program Files (x86)\Xming\Xming.exe"" :0 -clipboard -multiwindow", 0, False
CreateObject("Wscript.Shell").Run "bash -lic exit", 0, True
#+end_src

After making these, I copy shortcuts for that *last two* scripts above into my =shell:startup= folder. (You can access by typing that into the run dialog you get by hitting =Win + R=)

That will make this stuff all start on login, and without popping up any ugly command windows on startup. (That's why I used vbscript here--to squelch the command prompt popups)

* Startup services
To get Linux *services* starting on Windows start (Before anyone logs in), I create a startup script in /etc/ named after the user that will run it, so in my case, I call it =rc.arch.local=:
#+begin_src sh :tangle /sudo:root@localhost:/etc/rc.arch.local :tangle-mode (identity #o500)
#!/bin/bash
service cron start
service ssh start
#+end_src

I then add my user to a sudoers files to allow this to be run as root without a password:
#+begin_src sh :tangle /sudo:root@localhost:/etc/sudoers.d/archrc :tangle-mode (identity #o400)
# Startup script access for default user
archenoth ALL=(root) NOPASSWD: /etc/rc.arch.local
#+end_src

In Windows, I open up the Task Scheduler and make scheduled tasks to run the [[/sudo:root@localhost:/etc/rc.arch.local][/etc/rc.arch.local]] file with passwordless sudo when the computer starts.

This is what the task I made looks like exported as XML (You may need to change the user in here if you are planning on importing it into your Task Scheduler):
#+begin_src xml :tangle ~/Desktop/WSL rc.arch.local.xml



2019-11-08T12:49:06.8481246
JIRACHI\Archenoth
Starts the Linux Subsystem rc.arch.local script
\WSL rc.arch.local



true




S-1-5-21-3695860422-1816032588-548272057-1001
S4U
LeastPrivilege



IgnoreNew
false
true
true
true
false

true
false

true
true
false
false
false
PT72H
7



C:\Windows\System32\bash.exe
-c "sudo /etc/rc.arch.local"



#+end_src

I didn't bother with vbscript for this one since it runs before I even log on, so there still aren't any command prompt popups.

And that about covers the main tweaks I make! Feel free to steal as many of these ideas as you like..! ^^

* Tweaks
These aren't as major, but they are nice little things I sometimes enjoy being able to use.

** Using Linux programs from cmd.exe
I wrote a little Windows binary that, if you rename it to a Linux command, that Linux command will run. So if you like having git.exe on your path, you can use the Linux version with your Linux SSH config.

To set it up, you can run the following:
#+begin_src sh
mkdir -p /host/Oshawott/bin
wget https://github.com/Archenoth/wsl_proxy/releases/download/0.2.0/wsl_proxy.exe -O /host/Oshawott/wsl_proxy.exe

remaining=1023
find /bin /usr/bin /usr/local/bin /usr/sbin -executable -type f -maxdepth 1 ! -name bash -printf "%f\n" \
| sort | uniq | while read bin; do
echo "Linking $bin"
if [ "$remaining" -le "0" ]; then
remaining=1023
cp /host/Oshawott/wsl_proxy.exe /host/Oshawott/wsl_proxy2.exe
mv /host/Oshawott/wsl_proxy.exe "/host/Oshawott/bin/$bin.exe"
mv /host/Oshawott/wsl_proxy2.exe /host/Oshawott/wsl_proxy.exe
else
remaining=$((remaining-1))
ln /host/Oshawott/wsl_proxy.exe "/host/Oshawott/bin/$bin.exe"
fi
done
#+end_src

This will download the =wsl_proxy.exe= program, and link every executable in a number of bin folders likely on your =$PATH=. (We aren't gonna use =$PATH= proper since it will return many executables that aren't actually if you have any Windows paths in there)

The 1023 links per copy business is because each file can have only a maximum of 1024 links at any given time. (And yes, WSL hardlinks work on Windows)

To use this, you'll need to change your "Path" in =sysdm.cpl= under "Advanced" -> "Environment Variables" -> "User variables for " to include =C:\Oshawott\bin=.

** Run exes without writing ".exe"
You can use =command_not_found_handle= to automatically append =.exe= to your commands if they don't exist on Linux and try again.
All you need to do is modify the handle in [[/sudo:root@localhost:/etc/bash.bashrc::command_not_found_handle][bash.bashrc]] to look like:

#+begin_src sh
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
function command_not_found_handle {
if which "$1.exe" 1>/dev/null 2>&1; then
EXE="$1.exe"
shift
$EXE $*
return $?
else
# check because c-n-f could've been removed in the meantime
if [ -x /usr/lib/command-not-found ]; then
/usr/lib/command-not-found -- "$1"
return $?
elif [ -x /usr/share/command-not-found/command-not-found ]; then
/usr/share/command-not-found/command-not-found -- "$1"
return $?
else
printf "%s: command not found\n" "$1" >&2
return 127
fi
fi
}
fi
#+end_src

Since WSL does pathname translation, this means you can do crazy things like =explorer Code/ahk= and it will open that code folder with =explorer.exe= properly if it's in your $PATH!

*Note:* Programs run this way won't work on paths that only WSL can see. Which is another good reason to have [[Symlinks][symlinks between your two systems set up]]!

** Turn off dings every time you hit tab (And other things)
I don't really like how tab completion, or many other actions in Linux make my computer ding at me, so I like to replace the =bell-style= in [[/sudo:root@localhost:/etc/inputrc::bell-style][/etc/inputrc]] to be =set bell-style none=.

* Conclusion
I mostly wrote this file for myself, but if you stumbled across it somehow, I hope you found these tricks useful!