summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-01-28 23:21:09 +0800
committerGitHub <[email protected]>2026-01-28 23:21:09 +0800
commit45f856e3ccdec7da98ac7f07251f30d85640d268 (patch)
treea5704b90874b6387786f30ea2d16bcc7ba2ef589
parent11dd96c3a7edd0fbefbf3da80deab5b39fb347bf (diff)
parent5c99e2d9e452e08de4fd7595f4429790ce8efed7 (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.lua64
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
-