# Splitting the PATH variable

**URL:** <https://discourse.julialang.org/t/splitting-the-path-variable/72735>\
**Category:** General Usage\
**Tags:** question, filesystem\
**Created:** [December 7, 2021, 9:53pm UTC](https://discourse.julialang.org/t/splitting-the-path-variable/72735 "2021-12-07T21:53:35Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [December 7, 2021, 9:53pm UTC](https://discourse.julialang.org/t/splitting-the-path-variable/72735/1 "2021-12-07T21:53:35Z")

</div>

I want to re-order path entries.

On unix, `ENV["PATH"] = "/usr/local/bin:/usr/bin:/bin"` or some such.  
On windows, `ENV["PATH"] = "c:\\usr\\local\\bin;c:\\usr\\bin;c:\\bin"`  
But it could be `ENV["PATH"] = "c:\\usr\\local\\bin;c:\\usr\\bin;c:\\bin;\"c:\\usr\\directory name with; semicolon\\bin\""`, so `split(ENV["PATH"], Sys.iswindows() ? ";" : ":")` isn’t perfect. Is there a better way?

---

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [December 7, 2021, 11:23pm UTC](https://discourse.julialang.org/t/splitting-the-path-variable/72735/3 "2021-12-07T23:23:03Z")

</div>

PATH environment variables are not guaranteed to point to paths that exist in the system

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 7, 2021, 11:24pm UTC](https://discourse.julialang.org/t/splitting-the-path-variable/72735/4 "2021-12-07T23:24:12Z")

</div>

OK, nevermind.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [December 8, 2021, 12:37am UTC](https://discourse.julialang.org/t/splitting-the-path-variable/72735/5 "2021-12-08T00:37:24Z")

</div>

> [@Lilith](#):
>
> so `split(ENV["PATH"], Sys.iswindows() ? ";" : ":")` isn’t perfect.

Why do you care? Most tools won’t work anyway if `PATH` includes directories with the list separator in their own path. Try for example this on Linux:

```julia
% mkdir -p /tmp/tmp:dir
% echo 'echo hello world' > /tmp/tmp:dir/helloworld
% chmod +x /tmp/tmp:dir/helloworld
% /tmp/tmp:dir/helloworld
hello world
% export PATH="/tmp/tmp:dir:${PATH}"
% helloworld                  
zsh: command not found: helloworld

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 8, 2021, 10:25pm UTC](https://discourse.julialang.org/t/splitting-the-path-variable/72735/6 "2021-12-08T22:25:26Z")

</div>

For the Windows case, an attempt at a `splitpath()` function:

```julia
# Julia 1.7:
function splitpath(epath::String)
    isw() = Sys.iswindows()
    ix = findall(occursin("\""), epath)
    if !isempty(ix)
        i0, p0 = 1, String[]
        for i in 1:2:length(ix)
            append!(p0, replace.(string.(split(epath[i0:ix[i]-1], isw() ? ";" : ":")), "\""=>""))
            push!(p0, replace.(string(epath[ix[i]:ix[i+1]-1]), "\"" => ""))
            i0 = ix[i+1]
        end
        if length(epath) > ix[end]
            append!(p0, replace.(string.(split(epath[ix[end]+1:end], isw() ? ";" : ":")), "\""=>""))
        end
    else
        p0 = string.(split(epath, isw() ? ";" : ":"))
    end
    filter!(!isempty,p0)
    return p0
end

# INPUT:
epath = "c:\\usr\\local\\bin;c:\\usr\\bin;c:\\bin;\"c:\\usr\\directory name with; semicolon\\bin\";c:;\"c:\\directory2 with; semicolon\""

# OUTPUT:
splitpath(epath)

6-element Vector{String}:
 "c:\\usr\\local\\bin"
 "c:\\usr\\bin"
 "c:\\bin"
 "c:\\usr\\directory name with; semicolon\\bin"
 "c:"
 "c:\\directory2 with; semicolon"

```

---

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [December 8, 2021, 10:40pm UTC](https://discourse.julialang.org/t/splitting-the-path-variable/72735/7 "2021-12-08T22:40:10Z")

</div>

> [@giordano](#):
>
> Why do you care?

Honestly, I was hoping there was a builtin akin to `splitpath` and `joinpath` that would do it. Given the complexity of @rafael.guerra’s answer, I may well stick with not supporting path entries with `;`.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [December 8, 2021, 10:46pm UTC](https://discourse.julialang.org/t/splitting-the-path-variable/72735/8 "2021-12-08T22:46:51Z")

</div>

> [@Lilith](#):
>
> Given the complexity…

Sorry but simplicity requires more time and skill 🙂
