diff --git a/NEWS.md b/NEWS.md
index 6c378c8186007..71014e1e57695 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -97,6 +97,7 @@ New library functions
* `uuid7()` creates an RFC 9652 compliant UUID with version 7 ([#54834]).
* `insertdims(array; dims)` allows to insert singleton dimensions into an array which is the inverse operation to `dropdims`. ([#45793])
* The new `Fix` type is a generalization of `Fix1/Fix2` for fixing a single argument ([#54653]).
+* `Sys.detectwsl()` allows to testing if Julia is running inside WSL at runtime. ([#57069])
New library features
--------------------
diff --git a/base/sysinfo.jl b/base/sysinfo.jl
index 7dab313cf4f57..c96c318ec053b 100644
--- a/base/sysinfo.jl
+++ b/base/sysinfo.jl
@@ -36,7 +36,8 @@ export BINDIR,
isreadable,
iswritable,
username,
- which
+ which,
+ detectwsl
import ..Base: show
@@ -532,6 +533,27 @@ including e.g. a WebAssembly JavaScript embedding in a web browser.
"""
isjsvm(os::Symbol) = (os === :Emscripten)
+"""
+ Sys.detectwsl()
+
+Runtime predicate for testing if Julia is running inside
+Windows Subsystem for Linux (WSL).
+
+!!! note
+ Unlike `Sys.iswindows`, `Sys.islinux` etc., this is a runtime test, and thus
+ cannot meaningfully be used in `@static if` constructs.
+
+!!! compat "Julia 1.12"
+ This function requires at least Julia 1.12.
+"""
+function detectwsl()
+ # We use the same approach as canonical/snapd do to detect WSL
+ islinux() && (
+ isfile("/proc/sys/fs/binfmt_misc/WSLInterop")
+ || isdir("/run/WSL")
+ )
+end
+
for f in (:isunix, :islinux, :isbsd, :isapple, :iswindows, :isfreebsd, :isopenbsd, :isnetbsd, :isdragonfly, :isjsvm)
@eval $f() = $(getfield(@__MODULE__, f)(KERNEL))
end
diff --git a/test/osutils.jl b/test/osutils.jl
index 5e72675279cbc..9eb708b670298 100644
--- a/test/osutils.jl
+++ b/test/osutils.jl
@@ -29,6 +29,11 @@ using Libdl
else
@test Sys.windows_version() >= v"1.0.0-"
end
+
+ # TODO: When we have a WSL CI, add a new test here `@test detectwsl()`
+ if !Sys.islinux()
+ @test !Sys.detectwsl()
+ end
end
@testset "@static" begin
diff --git a/test/path.jl b/test/path.jl
index 2515d765d8ca9..a2824a24c8bce 100644
--- a/test/path.jl
+++ b/test/path.jl
@@ -314,7 +314,7 @@
@testset "uripath" begin
host = if Sys.iswindows()
""
- elseif ispath("/proc/sys/fs/binfmt_misc/WSLInterop")
+ elseif Sys.detectwsl()
distro = get(ENV, "WSL_DISTRO_NAME", "") # See
"wsl%24/$distro" # See and
else