diff options
| author | ruki <[email protected]> | 2026-01-28 23:21:09 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-01-28 23:21:09 +0800 |
| commit | 45f856e3ccdec7da98ac7f07251f30d85640d268 (patch) | |
| tree | a5704b90874b6387786f30ea2d16bcc7ba2ef589 | |
| parent | 11dd96c3a7edd0fbefbf3da80deab5b39fb347bf (diff) | |
| parent | 5c99e2d9e452e08de4fd7595f4429790ce8efed7 (diff) | |
Merge pull request #7267 from luadebug/linux-shell
enhance shell detection for Linux by checking parent process
| -rw-r--r-- | xmake/core/base/tty.lua | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/xmake/core/base/tty.lua b/xmake/core/base/tty.lua index dd053b3e6..b3ac35b2b 100644 --- a/xmake/core/base/tty.lua +++ b/xmake/core/base/tty.lua @@ -23,6 +23,7 @@ local tty = tty or {} -- load modules local io = require("base/io") +local path = require("base/path") -- save metatable and builtin functions tty._term_mode = tty._term_mode or tty.term_mode @@ -234,6 +235,59 @@ function tty.flush() return tty end +-- find the shell from the parent process (linux) +function tty._find_shell_from_parent() + if os.host() ~= "linux" or not os.isfile("/proc/self/stat") then + return + end + + local shell + local pid = os.getpid() + local count = 0 + while pid ~= 0 and count < 4 do + count = count + 1 + local shell_name = nil + local shell_path = nil + if os.isfile("/proc/" .. pid .. "/exe") then + local link = os.readlink("/proc/" .. pid .. "/exe") + if link then + shell_path = link + end + end + + if not shell_path and os.isfile("/proc/" .. pid .. "/comm") then + shell_name = io.readfile("/proc/" .. pid .. "/comm") + if shell_name then + shell_name = shell_name:trim() + end + end + if shell_path then + shell_name = path.filename(shell_path) + end + + if shell_name then + shell_name = shell_name:ltrim("-") + for _, name in ipairs({"zsh", "bash", "fish", "nu", "elvish", "pwsh", "sh"}) do + if shell_name == name then + shell = name + break + end + end + if shell then + break + end + end + + local stat = io.readfile("/proc/" .. pid .. "/stat") + local ppid = stat and tonumber(stat:match(".*%) %S+ (%d+)")) + if not ppid or ppid == 0 then + break + end + pid = ppid + end + return shell +end + -- get shell name function tty.shell() local shell = tty._SHELL @@ -256,13 +310,18 @@ function tty.shell() end end end + -- try to find the shell from the parent process (linux) + if not shell then + shell = tty._find_shell_from_parent() + end + if not shell then shell = os.getenv("XMAKE_SHELL") end if not shell then shell = os.getenv("SHELL") if shell then - for _, shellname in ipairs({"zsh", "bash", "sh"}) do + for _, shellname in ipairs({"zsh", "bash", "fish", "nu", "elvish", "pwsh", "sh"}) do if shell:find(shellname) then shell = shellname break @@ -323,6 +382,8 @@ function tty.term() term = "xterm" elseif TERM == "cygwin" then term = "cygwin" + elseif TERM:find("alacritty", 1, true) then + term = "alacritty" end end end @@ -560,4 +621,3 @@ end -- return module return tty - |
