sh: add POSIX-like -c support and complete shell subset gaps
Implement sh -c COMMAND [NAME [ARG...]] in /bin/sh, add shell function declarations/invocation support, expand export semantics (NAME, NAME=value, -p), and make until/loop-control behavior available by default. Add focused shell tests and update sh man-page option docs.
This commit is contained in:
+36
-3
@@ -88,9 +88,9 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const script = argv[1]
|
||||
if (script == null) {
|
||||
ctx.console.error('usage: sh SCRIPT')
|
||||
const mode = argv[1]
|
||||
if (mode == null) {
|
||||
ctx.console.error('usage: sh -c COMMAND [NAME [ARG ...]] | sh SCRIPT')
|
||||
ctx.exitCode = 2
|
||||
return
|
||||
}
|
||||
@@ -99,6 +99,39 @@ async function run(ctx, argv) {
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (mode === '-c') {
|
||||
const command = argv[2]
|
||||
if (command == null) {
|
||||
ctx.console.error('sh: option requires an argument -- c')
|
||||
ctx.console.error('usage: sh -c COMMAND [NAME [ARG ...]] | sh SCRIPT')
|
||||
ctx.exitCode = 2
|
||||
return
|
||||
}
|
||||
const env = ctx.vfs?.env
|
||||
/** @type {Record<string, string | undefined> | null} */
|
||||
const saved = env && typeof env === 'object' ? {} : null
|
||||
if (saved && env) {
|
||||
for (const k of ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#']) {
|
||||
saved[k] = env[k]
|
||||
}
|
||||
env['0'] = argv[3] ?? 'sh'
|
||||
const args = argv.slice(4)
|
||||
for (let i = 1; i <= 9; i++) env[String(i)] = args[i - 1] ?? ''
|
||||
env['#'] = String(args.length)
|
||||
}
|
||||
try {
|
||||
await ctx.execLine(command)
|
||||
} finally {
|
||||
if (saved && env) {
|
||||
for (const [k, v] of Object.entries(saved)) {
|
||||
if (v == null) delete env[k]
|
||||
else env[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
const script = mode
|
||||
let buf
|
||||
try {
|
||||
buf = await ctx.vfs.readFile(script)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"schema": 2,
|
||||
"profileId": "bare-os-posix-like",
|
||||
"generatedAt": "2026-04-26T19:04:18.264Z",
|
||||
"generatedAt": "2026-04-26T19:19:08.534Z",
|
||||
"note": "Sparse POSIX Issue 7 coverage hints for /bin utilities. Omitted command names are not yet profiled here.",
|
||||
"commandIndex": [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"atMs": 1777230258263,
|
||||
"atMs": 1777231148534,
|
||||
"commands": [
|
||||
"agent",
|
||||
"appctl",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"generatedAt": "2026-04-26T19:04:18.469Z",
|
||||
"generatedAt": "2026-04-26T19:19:08.715Z",
|
||||
"pages": [
|
||||
{
|
||||
"name": "agent",
|
||||
@@ -3211,8 +3211,13 @@
|
||||
"synopsis": [
|
||||
"sh [OPTION]... [OPERAND]..."
|
||||
],
|
||||
"description": "Runs a shell script file line-by-line via ctx.execLine (same language as the interactive booter shell). This is not the interactive REPL; see man bare-os-shell for session builtins, pipelines, and jobs.",
|
||||
"options": [],
|
||||
"description": "Runs shell commands via ctx.execLine (same language as the interactive booter shell). Supports command-string mode (`-c`) and script-file mode (`sh SCRIPT`). This is not the interactive REPL; see man bare-os-shell for session builtins, pipelines, and jobs.",
|
||||
"options": [
|
||||
{
|
||||
"flag": "-c COMMAND [NAME [ARG ...]]",
|
||||
"meaning": "Execute command string and set positional parameters for that command context."
|
||||
}
|
||||
],
|
||||
"keywords": [
|
||||
"sh",
|
||||
"bare-os",
|
||||
|
||||
Reference in New Issue
Block a user