Linux・WSL・Windows GitBash でクリップボードのコピー・ペーストを実現するコマンド

今までも何度か解説している、ターミナルでコピー・ペーストを行うコマンド。MacOS だと pbcopypbpaste というコマンドが標準搭載されていて、この使用感で Linux や WSL 環境、GitBash でもコピペがしたいと思うことがある。

最近、WSL 環境向けのスクリプトを以下のサイトで見たので、コレを基に改めてまとめてみた。

この記事では、WSL における pbcopyclip.exe で、pbpaste を PowerShell の Get-Clipboard で実現している。WSL 環境は素の Ubuntu と大差なく、GUI 環境を用意しておけば xclip をインストールしても動いたと記憶しているが、apt でのインストールが要らない手法で実現されていると助かる。

# WSL で GUI 環境がないと、xclip を使おうとしてお次のようなエラーが出てしまう
$ xclip -selection c
Error: Can't open display: (null)

powershell.execlip.exe への PATH は通っていることが多いし、そうでなくても wslpath で変換後のフルパスを書けば良いかなと思うので、だいぶシンプルにできると思った。

# pbcopy コマンドを実現する Bash 関数
# /mnt/c/Windows/System32/clip.exe
function pbcopy() {
  tee <&0 | clip.exe
}

# pbpaste コマンドを実現する Bash 関数
# /mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe
function pbpaste() {
  powershell.exe Get-Clipboard | sed 's/\r$//' | sed -z '$ s/\n$//'
}

そんなワケで、次のような ~/.bashrc 用のセットアップスクリプトを組んでみた。

if [ "$(uname)" == 'Linux' ]; then
  # For Linux
  if type xclip > /dev/null 2>&1; then
    alias pbcopy='xclip -selection c'
    alias pbpaste='xclip -selection c -o'
  fi
  
  # For WSL
  if [[ "$(uname -r)" == *microsoft* ]]; then
    if type pbcopy > /dev/null 2>&1; then
      unalias pbcopy
    fi
    if type pbpaste > /dev/null 2>&1; then
      unalias pbpaste
    fi
    
    function pbcopy() {
      tee <&0 | clip.exe
    }
    function pbpaste() {
      powershell.exe Get-Clipboard | sed 's/\r$//' | sed -z '$ s/\n$//'
    }
  fi
elif [[ "$(uname)" == *MSYS* ]]; then
  # For Git SDK
  
  if ! type pbcopy.exe > /dev/null 2>&1; then
    alias pbcopy='cat > /dev/clipboard'
  fi
  if ! type pbpaste.exe > /dev/null 2>&1; then
    alias pbpaste='cat /dev/clipboard'
  fi
fi

Linux および WSL 環境向けに if ブロックを組み、まずは xcilp の有無でエイリアスを作る。

次に Linux 環境の中でも WSL 環境の場合はさらに if ブロックをネストして、エイリアスがあれば削除して、先程の Bash 関数を宣言する。

最後に MSYS を含むかどうかで GitBash (Git SDK) 環境を判定する。pbcopy.exepbpaste.exe を用意して PATH を通してあるなら何もせず、そうでなければ /dev/clipboard を使うイディオムをエイリアスに宣言しておく、というワケだ。

コレでほぼどんな環境でも pbcopypbpaste が使えるだろう。