Skip to content

Commit 826e79c

Browse files
committed
fix(exec): restore non-interactive shell helper and sh fallback
1 parent 8d1841b commit 826e79c

1 file changed

Lines changed: 22 additions & 1 deletion

File tree

src/agents/shell-utils.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ export function resolvePowerShellPath(): string {
3838
return "powershell.exe";
3939
}
4040

41+
// Non-interactive placeholder shells that reject "-c"-style invocations.
42+
// macOS LaunchDaemon service users commonly use /usr/bin/false so login sessions
43+
// cannot be opened; honoring SHELL in that case causes every exec to exit 1.
44+
// See https://github.com/openclaw/openclaw/issues/69077.
45+
const NON_INTERACTIVE_SHELLS = new Set(["false", "nologin"]);
46+
47+
function isNonInteractiveShell(shellPath: string): boolean {
48+
if (!shellPath) {
49+
return false;
50+
}
51+
return NON_INTERACTIVE_SHELLS.has(path.basename(shellPath));
52+
}
53+
4154
function resolvePosixShellArgs(shellPath: string): string[] {
4255
const shellName = normalizeShellName(shellPath);
4356

@@ -82,7 +95,15 @@ export function getShellConfig(): { shell: string; args: string[] } {
8295
return { shell: sh, args: resolvePosixShellArgs(sh) };
8396
}
8497
}
85-
const shell = envShell && envShell.length > 0 ? envShell : "sh";
98+
99+
if (envShell) {
100+
return { shell: envShell, args: resolvePosixShellArgs(envShell) };
101+
}
102+
103+
// Placeholder SHELL (or unset): prefer a resolved sh/bash on PATH so we do not
104+
// re-invoke the placeholder and get a spurious exitCode=1.
105+
const sh = resolveShellFromPath("sh") ?? resolveShellFromPath("bash");
106+
const shell = sh ?? "sh";
86107
return { shell, args: resolvePosixShellArgs(shell) };
87108
}
88109

0 commit comments

Comments
 (0)