Fix the termninal
Release rolling / release (push) Successful in 9m48s

This commit is contained in:
Raven Scott
2026-07-13 17:43:08 -04:00
parent ac754d6f5a
commit 50c43ff2e9
2 changed files with 21 additions and 5 deletions
+6 -5
View File
@@ -57,12 +57,13 @@ export const DEFAULT_SHELL_CANDIDATES = Object.freeze([
/**
* One-shot script: from a working sh, pick the best available interactive shell.
* Used when /bin/sh (or equivalent) exists but we still want bash if present.
*
* Must be valid when passed to `sh -c`. Join with newlines (not spaces):
* space-joining turns `done\\nfor` into `done for`, which dash/sh reject
* as `Syntax error: "if" unexpected (expecting "done")`.
*/
const SHELL_PROBE_SCRIPT = [
'for s in /bin/bash /usr/bin/bash bash /bin/zsh /usr/bin/zsh zsh',
'/bin/ash /usr/bin/ash ash /bin/dash /usr/bin/dash dash',
'/bin/ksh /usr/bin/ksh ksh /bin/mksh /usr/bin/mksh mksh',
'/bin/fish /usr/bin/fish fish; do',
'for s in /bin/bash /usr/bin/bash bash /bin/zsh /usr/bin/zsh zsh /bin/ash /usr/bin/ash ash /bin/dash /usr/bin/dash dash /bin/ksh /usr/bin/ksh ksh /bin/mksh /usr/bin/mksh mksh /bin/fish /usr/bin/fish fish; do',
' if [ -x "$s" ]; then exec "$s"; fi',
' if command -v "$s" >/dev/null 2>&1; then exec "$s"; fi',
'done',
@@ -73,7 +74,7 @@ const SHELL_PROBE_SCRIPT = [
'if [ -x /bin/sh ]; then exec /bin/sh; fi',
'if [ -x /usr/bin/sh ]; then exec /usr/bin/sh; fi',
'exit 127',
].join(' ')
].join('\n')
/** Bootstrap wrappers that run SHELL_PROBE_SCRIPT. */
const PROBE_WRAPPERS = Object.freeze([
+15
View File
@@ -7,6 +7,21 @@ import {
buildShellCandidates,
} from '../server/handlers/terminal.js'
test('probe wrapper -c script keeps newlines (valid sh -c)', (t) => {
const list = buildShellCandidates({})
const probe = list.find((c) => c.includes('-c') && c.some((p) => String(p).includes('exec')))
t.ok(probe, 'probe candidate exists')
const script = probe.find(
(p) => typeof p === 'string' && p.includes('exec') && p.includes('for s in')
)
t.ok(script, 'probe script payload present')
t.ok(String(script).includes('\n'), 'script uses newlines between statements')
// Space-joined scripts become `done for` / `done if` and break dash/sh -c
t.absent(/\bdone for\b/.test(String(script)))
t.absent(/\bdone if\b/.test(String(script)))
t.ok(/\ndone\nfor\b/.test(String(script)), 'second loop follows done on a new line')
})
test('DEFAULT_SHELL_CANDIDATES includes bash, sh, ash, busybox', (t) => {
const flat = DEFAULT_SHELL_CANDIDATES.map((c) => c.join(' '))
t.ok(flat.some((s) => s.includes('bash')))