How to get username?

How do I get the username of the user running the julia process?

On Linux I can do

ENV["USER"]

and on Windows:

ENV["USERNAME"]

But I don’t know what to do on other operating systems.

What is the os-independent way to ask for the username?

run in Julia REPL

run(`sh -c 'echo $USER'`)

I can’t do ENV["USER"]

to obtain username in my OS I need to echo $USER

Capture d’écran_2023-01-16_19-11-47

Capture d’écran_2023-01-16_19-13-11

I am not sure if something like this is available. Python has getpass.getuser, which only checks the environment variables LOGNAME, USER, LNAME, and USERNAME. So probably you could use something like

function username()
    varnames = ["LOGNAME", "USER", "LNAME",  "USERNAME"]
    for varname in varnames
        haskey(ENV, varname) && return ENV[varname]
    end
    return nothing
end
2 Likes

Thank you @barucden .

If it’s good enough for python it is good enough for me :smile:

I’m just a bit surprised there isn’t a standard function in Julia to get this.
When we have homedir() I would expect we also had username().

The reason we don’t have such a function might be that nobody requested it so far. If you think it should be in Julia base, then consider creating an issue.

To be precise, the python function does more than what I sketched:

If none are set, the login name from the password database is returned on systems which support the pwd module, otherwise, an exception is raised.

Our homedir() function is based on libuv, which also seems to provide a way to get a username from passwd. It shouldn’t be too hard to basically mirror python’s functionality (i.e., try the environment variables and potentially resort to passwd).

3 Likes

Something like:

struct uv_passwd
    username::Cstring
    uid::Clong
    gid::Clong
    shell::Cstring
    homedir::Cstring
end

function username()
    for varname in ("LOGNAME", "USER", "LNAME",  "USERNAME")
        username = get(ENV, varname, "")
        !isempty(username) && return username
    end
    p = Ref{uv_passwd}()
    ret = @ccall uv_os_get_passwd(p::Ref{uv_passwd})::Cint
    Base.uv_error("get_passwd", ret)
    username = unsafe_string(p[].username)
    @ccall uv_os_free_passwd(p::Ref{uv_passwd})::Cvoid
    return username
end

Note also that you should check whether the environment variables are non-empty, not just whether they exist. This is what Python does.

Update: Alternatively, Julia’s Libc module apparently already contains an undocumented function for this, though it doesn’t check the environment variables first:

julia> Libc.getpwuid(Libc.getuid(), true)
Base.Libc.Passwd("stevenj", 0x00000000000001f5, 0x0000000000000014, "/bin/zsh", "/Users/stevenj", "Steven G. Johnson")

julia> Libc.getpwuid(Libc.getuid(), true).username
"stevenj"

I filed an issue: username() function (analogous to homedir()) · Issue #48302 · JuliaLang/julia · GitHub

8 Likes

Thank you very much @stevengj .

Looks like this can go right into a PR :smile: