<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Emmie Päivärinta</title>
    <description>The latest articles on Forem by Emmie Päivärinta (@emmiep).</description>
    <link>https://forem.com/emmiep</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F294916%2F67a308f4-5d02-41a6-b227-f02ed807181a.png</url>
      <title>Forem: Emmie Päivärinta</title>
      <link>https://forem.com/emmiep</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/emmiep"/>
    <language>en</language>
    <item>
      <title>Better Copy and Paste in WSL with Two One-Liner Aliases</title>
      <dc:creator>Emmie Päivärinta</dc:creator>
      <pubDate>Mon, 13 Jun 2022 17:06:37 +0000</pubDate>
      <link>https://forem.com/emmiep/better-copy-and-paste-in-wsl-with-two-one-liner-aliases-ldm</link>
      <guid>https://forem.com/emmiep/better-copy-and-paste-in-wsl-with-two-one-liner-aliases-ldm</guid>
      <description>&lt;p&gt;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?&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://www.manpagez.com/man/1/pbcopy/"&gt;&lt;code&gt;pbcopy&lt;/code&gt; and &lt;code&gt;pbpaste&lt;/code&gt; command-line tools&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;pbcopy&lt;/code&gt; and &lt;code&gt;pbpaste&lt;/code&gt; commands to WSL with a couple of one-liner command-line aliases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;We're going to define two aliases in our WSL Linux shell. &lt;code&gt;pbcopy&lt;/code&gt; sets the clipboard contents from its input, and &lt;code&gt;pbpaste&lt;/code&gt; outputs it. Creating aliases in the shell is done with the &lt;code&gt;alias&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;pbcopy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'powershell.exe -Command "Set-Clipboard -Value \$input"'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;pbpaste&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'powershell.exe -Command "Get-Clipboard"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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 (&lt;code&gt;~&lt;/code&gt;), but the filename depends on the shell. For Bash this file is called &lt;a href="https://linuxhint.com/bash_alias/"&gt;&lt;code&gt;.bashrc&lt;/code&gt;&lt;/a&gt;, and for ZSH it is &lt;a href="https://linuxhint.com/configure-use-aliases-zsh/"&gt;&lt;code&gt;.zshrc&lt;/code&gt;&lt;/a&gt;. The changes will only take effect after starting a new shell.&lt;/p&gt;

&lt;p&gt;Let's put the aliases to the test with some commands. First, we'll get a random UUID by copying the output of &lt;code&gt;uuidgen&lt;/code&gt; with &lt;code&gt;pbcopy&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uuidgen | pbcopy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, let's use a copied JSON document as the body of an HTTP POST request by piping the output of &lt;code&gt;pbpaste&lt;/code&gt; to &lt;code&gt;curl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pbpaste | curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; @- https://httpbin.org/post
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Aliases
&lt;/h2&gt;

&lt;p&gt;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 (&lt;code&gt;|&lt;/code&gt;). The pipe passes output from the first command to the input of the next.&lt;/p&gt;

&lt;p&gt;Piping the output from a command to &lt;code&gt;pbcopy&lt;/code&gt; copies it to the clipboard. For instance, to get the current UNIX time, create a pipe from &lt;code&gt;date&lt;/code&gt; to &lt;code&gt;pbcopy&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s | pbcopy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand, piping the output of &lt;code&gt;pbpaste&lt;/code&gt; to another command will use the clipboard contents as its input. A Gist can easily be created from the clipboard contents by piping from &lt;code&gt;pbpaste&lt;/code&gt; to the awesome &lt;a href="https://cli.github.com/"&gt;&lt;code&gt;gh&lt;/code&gt; GitHub CLI tool&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pbpaste | gh gist create &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"Gist created with pbpaste"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"gist-filename.txt"&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to pipes, redirects make copying and pasting files effortless. By appending &lt;code&gt;&amp;gt;&lt;/code&gt; and a file path to a command, its output is redirected to that file. This way, redirecting the output of &lt;code&gt;pbpaste&lt;/code&gt; creates a file from the clipboard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pbpaste &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be aware output redirects overwrite existing files. To append the output to the end of a file, use &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; instead. This can for instance be used to add lines to the Bash configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pbpaste &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, the contents of a file can be redirected to the input of a command with &lt;code&gt;&amp;lt;&lt;/code&gt;. This lets you copy entire files with &lt;code&gt;pbcopy&lt;/code&gt;, for instance, your public SSH key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pbcopy &amp;lt; ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Avoiding Pitfalls of Copy and Paste
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;When using the aliases you don't have to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;remove extra newlines when copying multiple lines&lt;/li&gt;
&lt;li&gt;add quotes and escape characters when pasting&lt;/li&gt;
&lt;li&gt;worry about copying too many or too few characters&lt;/li&gt;
&lt;li&gt;worry about secrets being visible&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementing the Aliases
&lt;/h2&gt;

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

&lt;p&gt;Conveniently, the PowerShell shell – which comes pre-installed with Windows – has just what we're looking for. Open &lt;em&gt;Windows PowerShell&lt;/em&gt; or &lt;em&gt;Windows Terminal&lt;/em&gt; to try out the following PowerShell commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Write-Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello PowerShell!"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Set-Clipboard&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Get-Clipboard&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, &lt;a href="https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Management/Set-Clipboard?view=powershell-7.2&amp;amp;viewFallbackFrom=powershell-5.0"&gt;&lt;code&gt;Set-Clipboard&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Management/Get-Clipboard?view=powershell-7.2&amp;amp;viewFallbackFrom=powershell-5.0"&gt;&lt;code&gt;Get-Clipboard&lt;/code&gt;&lt;/a&gt; give us the functionality we need for implementing &lt;code&gt;pbcopy&lt;/code&gt; and &lt;code&gt;pbpaste&lt;/code&gt;. However, we still need to find a way to run these commands inside WSL. Starting PowerShell inside WSL is as simple as typing &lt;code&gt;powershell.exe&lt;/code&gt;. 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 &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe?view=powershell-5.1#-command"&gt;&lt;code&gt;-Command&lt;/code&gt; flag&lt;/a&gt; lets us do just that. Armed with this knowledge we can run &lt;code&gt;Get-Clipboard&lt;/code&gt; again, but this time from Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;powershell.exe &lt;span class="nt"&gt;-Command&lt;/span&gt; &lt;span class="s2"&gt;"Get-Clipboard"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Hello WSL!'&lt;/span&gt; | powershell.exe &lt;span class="nt"&gt;-Command&lt;/span&gt; &lt;span class="s2"&gt;"Set-Clipboard -Value &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="s2"&gt;input"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to escape the &lt;code&gt;$&lt;/code&gt; with a slash because &lt;code&gt;$input&lt;/code&gt; is a variable in PowerShell. If not, Linux would substitute it before running &lt;code&gt;powershell.exe&lt;/code&gt; and it would be the wrong value.&lt;/p&gt;

&lt;p&gt;We can now finally both copy &lt;em&gt;and&lt;/em&gt; 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 &lt;code&gt;alias&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;pbcopy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'powershell.exe -Command "Set-Clipboard -Value \$input"'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;pbpaste&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'powershell.exe -Command "Get-Clipboard"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At last, we've arrived back where we began in 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;pbcopy&lt;/code&gt; and &lt;code&gt;pbpaste&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;A big advantage of clipboard command-line tools is being able to copy from and paste to other commands using &lt;em&gt;pipes&lt;/em&gt;, and to and from files using &lt;em&gt;redirects&lt;/em&gt;. Pipes make it trivial to connect clipboard commands to most command-line tools, such as &lt;code&gt;gh&lt;/code&gt; for creating Gists from the clipboard, or &lt;code&gt;uuidgen&lt;/code&gt; for copying random UUID values.&lt;/p&gt;

&lt;p&gt;I hope &lt;code&gt;pbcopy&lt;/code&gt; and &lt;code&gt;pbpaste&lt;/code&gt; 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.&lt;/p&gt;




&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@joszczepanska?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Jo Szczepanska&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>windows</category>
      <category>wsl</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
