WSLでWindowsのディレクトリパスが欲しい

(2020.03.02追記)

実は途中から「これ絶対に要望を満たすコマンド実装されてるよなー、誰か作ってるよなー」とか思いながら作成していたのですが本当にあって思わず笑ってしまった。wslpathというものが実装されています。

❯ which wslpath
/bin/wslpath
❯ wslpath -w "/mnt/d/"
D:\
❯ wslpath -w "/mnt/d/hoge"
wslpath: /mnt/d/hoge: No such file or directory

上を見ての通り存在しないディレクトリはNo such file or directoryと教えてくれるナイスな感じなので、もうこれを使用すればいいのでは?となった。私個人としてはfishの経験値が少し積めただけ良しとしましょう…。

(追記おわり)

WSLで操作を行う際にWindows上のディレクトリパスが欲しいことがありましたので、fishのシェルスクリプトとして作成しました。そのメモです。ちなみに動作はこのような感じです。

❯ winpath "/mnt/e/hoge/to/fuga"
E:\hoge\to\fuga
❯ winpath "/mnt/d"
D:\
❯ winpath "/mnt/hoge/to/fuga"
Drive letter is not 1 letter.
❯ winpath "/mnt"
Don't open /mnt directory.

環境

❯ fish -v
fish, version 2.7.1

2.7 ですが、最新は3.1らしい。

コード

ちなみにシェルスクリプトで行うことは引数で与えられた文字列の操作だけですので難しいものではありません。

❯ cat winpath.fish
function winpath

  # check argv
  if test (string match -r "^/" $argv)
    set list (string split "/" $argv)
  else
    echo "Directory path must include leading slash."
    return 1
  end

  # $list[0],[1] = null
  # $list[2] = "mnt"
  # $list[3] = c or d or ...(drive letter)
  # $list[4],[5],... = directory path

  # check $list[2]
  if not test (string match -r "mnt" $list[2])
    echo "Directory path must contains \"mnt\"."
    return 1
  end

  # check count $list and $list[3]
  switch (count $list)
    case 2
      echo "Don't open /mnt directory."
      return 1
    case 3
      set path ""
    case "*"
      if test (string match -r "^[a-z]{1}\$" $list[3])
        set path (for i in (seq 4 (count $list))
          echo $list[$i]
        end | string join "\\")
        # aaa\bbb\ccc\ddd
      else
        echo "Drive letter is not 1 letter."
        return 1
      end
  end

  set path (string join ":\\" (string upper $list[3]) $path)
  # D:\aaa\bbb\ccc\ddd

  echo $path
end

コード中の$list[3]がディレクトリパスのドライブレターとなります。それがWindowsで認識しているドライブレターと合致しているかの判断もしようかと思いましたがそこまでは出来ていません。そのためWindowsに存在しないディレクトリパスも普通に表示されてしまいます。エラー処理が適当な箇所も含めもう少しどうにかしたい。

© てっくらのーと/mkr-note 2024