1

Is it possible to access a symlink created in WSL from an R session running on the Windows host?

I've made a symlink in WSL. The link is not broken. I can view the contents in WSL using nano /path_to_symlink/mylink.txt. I can even open an R session in WSL and read the contents into a variable with x <- readLines("/path_to_symlink/mylink.txt") and verify the contents are as expected. However, I can't do the same in RStudio running on the Windows host. I can read files from the Windows host if they are not symlinks. Trying to read the symlink from Windows results in the following error message. Is there any way I can run my script in Windows without this message? I have good reason not to run it in WSL, but that is what I plan to do for now.

Error in file(con, "r") : cannot open the connection
2. file(con, "r")
1. readLines("//wsl.localhost/Ubuntu-22.04/home/mylink.txt")

In addition: Warning message:
In file(con, "r") :
  cannot open file '//wsl.localhost/Ubuntu-22.04/home/mylink.txt': No such file or directory

I do see "mylink.txt" in the output of list.files("//wsl.localhost/Ubuntu-22.04/home/") when run from Windows.

3
  • 1
    do you have wsl.localhost mapped as a network drive? Commented Oct 21 at 17:21
  • I believe so. In windows explorer I see the Linux Penguin and it is labeled as Linux. There are two subfolder that have the icon of a folder with the green wire that usually indicates a network storage location. One of them is \\wsl.localhost\Ubuntu-22.04. The other is \\wsl.localhost\wsl-vpnkit. Commented Oct 21 at 17:48
  • This is starting to look like a windows issue. I can't open or read the file in window file explorer. I can open other txt files that are not sym links. This webpage also supports that theory. I'm now stuck wondering if there are any clever work arounds short of running the script on WSL. blog.trailofbits.com/2024/02/12/… Commented Oct 21 at 17:58

1 Answer 1

1

I guess there's also a reason for not moving files out of WSL, which in turn might limit viable options. But ... for functions that handle URLs or connections, you could serve files from WSL over http.

Python http.server module as a server in WSL:

margusl@i:~/tmp$ ls -l
total 4
-rw-r--r-- 1 margusl margusl 145 Oct 22 01:17 file.txt
lrwxrwxrwx 1 margusl margusl   8 Oct 22 01:17 link.txt -> file.txt

margusl@i:~/tmp$ ip addr show eth0 | grep -w inet
    inet 172.22.204.92/20 brd 172.22.207.255 scope global eth0

margusl@i:~/tmp$ python3 -m http.server -b 172.22.204.92
Serving HTTP on 172.22.204.92 port 8000 (http://172.22.204.92:8000/) ...
172.22.192.1 - - [22/Oct/2025 01:17:59] "GET /file.txt HTTP/1.1" 200 -
172.22.192.1 - - [22/Oct/2025 01:17:59] "GET /link.txt HTTP/1.1" 200 -

R Session on Win host:

wsl_base <- r"(\\wsl.localhost\Ubuntu\home\margusl\tmp)"
url_base <- "http://172.22.204.92:8000"

# reading links fails:
list.files(wsl_base, pattern = "link", full.names = TRUE) |> readLines() 
#> Warning in file(con, "r"): cannot open file
#> '\\wsl.localhost\Ubuntu\home\margusl\tmp/link.txt': No such file or directory
#> Error in file(con, "r"): cannot open the connection

# file list through wsl path, file access over http:
( l <- list.files(wsl_base) )
#> [1] "file.txt" "link.txt"

file.path(url_base, l) |> 
  setNames(l) |> 
  print() |>
  lapply(readLines) |> 
  lapply(paste0, collapse = "\n") |>
  lapply(cat, "\n") |> 
  invisible()
#>                             file.txt                             link.txt 
#> "http://172.22.204.92:8000/file.txt" "http://172.22.204.92:8000/link.txt" 
#>  _____
#> < WSL >
#>  -----
#>         \   ^__^
#>          \  (oo)\_______
#>             (__)\       )\/\
#>                 ||----w |
#>                 ||     || 
#>  _____
#> < WSL >
#>  -----
#>         \   ^__^
#>          \  (oo)\_______
#>             (__)\       )\/\
#>                 ||----w |
#>                 ||     ||

# writing to file.txt, reading from link.txt url
write.table(head(mtcars), file.path(wsl_base, "file.txt"))
read.table(file.path(url_base, "link.txt"))
#>                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
#> Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#> Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#> Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#> Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#> Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
#> Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

it can get bit fiddly if you need to follow directory links, though http.server does provide listings. And it will follow links outside of server root - https://docs.python.org/3/library/http.server.html#security-considerations

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.