Better Copy and Paste in WSL with Two One-Liner Aliases
Tags: linux, windows, wsl, tooling
Published: 2022-06-13 17:06:37

Don't you hate it when the JSON document copied from the terminal doesn't work because of extra newlines? Or getting a syntax error because the string you pasted into the terminal needs to be escaped?

Before getting a Windows laptop a while ago I primarily used macOS for over a decade. From macOS, I'm used to having the convenient [`pbcopy` and `pbpaste` command-line tools](https://www.manpagez.com/man/1/pbcopy/) for copying and pasting in the terminal. Not only do they sidestep these problems, but they also make it a breeze to use almost any command-line tool together with the clipboard.

So understandably, I felt bummed out when I started using WSL to run a Linux shell inside Windows and realized it doesn't come with similar clipboard tools. Luckily, we can easily add our own `pbcopy` and `pbpaste` commands to WSL with a couple of one-liner command-line aliases.

## Getting Started

We're going to define two aliases in our WSL Linux shell. `pbcopy` sets the clipboard contents from its input, and `pbpaste` outputs it. Creating aliases in the shell is done with the `alias` command:

```sh
alias pbcopy='powershell.exe -Command "Set-Clipboard -Value \$input"'
alias pbpaste='powershell.exe -Command "Get-Clipboard"'
```

The aliases can be used immediately, but will only last until the end of the session. To make sure they'll always be available, we need to add them to our shell configuration file. The configuration file lives in the home directory (`~`), but the filename depends on the shell. For Bash this file is called [`.bashrc`](https://linuxhint.com/bash_alias/), and for ZSH it is [`.zshrc`](https://linuxhint.com/configure-use-aliases-zsh/). The changes will only take effect after starting a new shell.

Let's put the aliases to the test with some commands. First, we'll get a random UUID by copying the output of `uuidgen` with `pbcopy`:

```sh
uuidgen | pbcopy
```

Then, let's use a copied JSON document as the body of an HTTP POST request by piping the output of `pbpaste` to `curl`:

```sh
pbpaste | curl -H "Content-Type: application/json" -d @- https://httpbin.org/post
```

By simply defining two short command-line aliases we can now use the clipboard with almost any Linux tool. In the next section, we'll explore some more interesting usages.

## Using the Aliases

Most often we'll use the aliases when piping to and from other commands. A pipe is created by separating two commands with a pipe symbol (`|`). The pipe passes output from the first command to the input of the next.

Piping the output from a command to `pbcopy` copies it to the clipboard. For instance, to get the current UNIX time, create a pipe from `date` to `pbcopy`:

```sh
date +%s | pbcopy
```

On the other hand, piping the output of `pbpaste` to another command will use the clipboard contents as its input. A Gist can easily be created from the clipboard contents by piping from `pbpaste` to the awesome [`gh` GitHub CLI tool](https://cli.github.com/):

```sh
pbpaste | gh gist create -d "Gist created with pbpaste" -f "gist-filename.txt" -
```

In addition to pipes, redirects make copying and pasting files effortless. By appending `>` and a file path to a command, its output is redirected to that file. This way, redirecting the output of `pbpaste` creates a file from the clipboard:

```sh
pbpaste > index.js
```

Be aware output redirects overwrite existing files. To append the output to the end of a file, use `>>` instead. This can for instance be used to add lines to the Bash configuration file:

```sh
pbpaste >> ~/.bashrc
```

Lastly, the contents of a file can be redirected to the input of a command with `<`. This lets you copy entire files with `pbcopy`, for instance, your public SSH key:

```sh
pbcopy < ~/.ssh/id_rsa.pub
```

## Avoiding Pitfalls of Copy and Paste

In the previous sections, we've seen how the aliases make using the clipboard in the terminal more streamlined and enjoyable. But there are still even more benefits. The aliases solve many pitfalls of manual copy and paste in the terminal.

When using the aliases you don't have to:

- remove extra newlines when copying multiple lines
- add quotes and escape characters when pasting
- worry about copying too many or too few characters
- worry about secrets being visible

## Implementing the Aliases

Before wrapping up, let's take a look at how the clipboard aliases are implemented. You might have heard WSL lets you [run `.exe` files inside Linux](https://docs.microsoft.com/en-us/windows/wsl/filesystems#run-windows-tools-from-linux). This means we should be able to access the clipboard from WSL by using Windows command-line clipboard tools.

Conveniently, the PowerShell shell – which comes pre-installed with Windows – has just what we're looking for. Open _Windows PowerShell_ or _Windows Terminal_ to try out the following PowerShell commands:

```powershell
Write-Output "Hello PowerShell!" | Set-Clipboard
Get-Clipboard
```

As you can see, [`Set-Clipboard`](https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Management/Set-Clipboard?view=powershell-7.2&viewFallbackFrom=powershell-5.0) and [`Get-Clipboard`](https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Management/Get-Clipboard?view=powershell-7.2&viewFallbackFrom=powershell-5.0) give us the functionality we need for implementing `pbcopy` and `pbpaste`. However, we still need to find a way to run these commands inside WSL. Starting PowerShell inside WSL is as simple as typing `powershell.exe`. This will start an interactive shell though, which isn't what we want. Instead, we need a way to immediately run the commands and then exit. The [`-Command` flag](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe?view=powershell-5.1#-command) lets us do just that. Armed with this knowledge we can run `Get-Clipboard` again, but this time from Linux:

```sh
powershell.exe -Command "Get-Clipboard"
```

Now that pasting works, let's take a moment to look at copying. This time we have to pipe data to `powershell.exe`, which is a bit more involved. For this we can use [the `$input` variable](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-7.2#input) which is automatically created for us in PowerShell. Passing it to the `-Value` parameter of `Set-Clipboard` will set the clipboard from the data piped into PowerShell:

```sh
echo 'Hello WSL!' | powershell.exe -Command "Set-Clipboard -Value \$input"
```

Remember to escape the `$` with a slash because `$input` is a variable in PowerShell. If not, Linux would substitute it before running `powershell.exe` and it would be the wrong value.

We can now finally both copy _and_ paste inside WSL. But since we'd rather not type long and hard-to-remember commands over and over, we'll define aliases in the Linux shell. This is done with the `alias` command:

```sh
alias pbcopy='powershell.exe -Command "Set-Clipboard -Value \$input"'
alias pbpaste='powershell.exe -Command "Get-Clipboard"'
```

At last, we've arrived back where we began in [Getting Started](#getting-started). With the help of PowerShell, WSL, Linux, and just two lines of code, we now have commands for copying and pasting in the Linux shell.

## Conclusion

Manually copying and pasting in the terminal is fraught with problems and annoyances. Clipboard command-line tools avoid many of these issues and integrate nicely with other tools. macOS comes with the built-in `pbcopy` and `pbpaste` commands, but getting the same functionality when running a Linux shell with WSL isn't as obvious. In this article, we created similar commands for WSL as command-line aliases.

A big advantage of clipboard command-line tools is being able to copy from and paste to other commands using _pipes_, and to and from files using _redirects_. Pipes make it trivial to connect clipboard commands to most command-line tools, such as `gh` for creating Gists from the clipboard, or `uuidgen` for copying random UUID values.

I hope `pbcopy` and `pbpaste` will help improve your everyday terminal workflow, just as they have for me. Either way, hopefully, this article shed some light on how to integrate Windows and Linux tools using the features of WSL, and inspired you to explore more ways to enhance your terminal experience.

---

Photo by [Jo Szczepanska](https://unsplash.com/@joszczepanska?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)