@@ -0,0 +1,12 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
globalThis.console.clear?.()
|
||||
const w = globalThis.process?.stdout?.write
|
||||
if (typeof w === 'function') {
|
||||
w.call(globalThis.process.stdout, '\x1b[2J\x1b[3J\x1b[H')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const utc = argv.includes('-u') || argv.includes('--utc')
|
||||
const d = new Date()
|
||||
ctx.console.log(
|
||||
utc
|
||||
? d
|
||||
.toISOString()
|
||||
.replace('T', ' ')
|
||||
.replace(/\.\d{3}Z$/, ' UTC')
|
||||
: d.toString()
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const e = ctx.vfs.env
|
||||
for (const k of Object.keys(e).sort()) {
|
||||
ctx.console.log(k + '=' + (e[k] ?? ''))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
+1
-1
@@ -5,6 +5,6 @@ function bareStdin(ctx) {
|
||||
|
||||
async function run(ctx, argv) {
|
||||
ctx.console.log(
|
||||
'Bare OS userland — builtins: cd, export, exit | /bin: ls pwd cat echo test basename dirname wc head tail uname pathchk help'
|
||||
'Bare OS — builtins: cd, export, exit | /bin: basename cat clear date dirname echo env false head help hostname id ls nl pathchk printenv pwd rm seq sleep sort tail test touch true tty uname wc which whoami'
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const h =
|
||||
globalThis.process?.env?.HOSTNAME ||
|
||||
globalThis.process?.env?.COMPUTERNAME ||
|
||||
ctx.vfs.env.HOSTNAME ||
|
||||
'bare-os'
|
||||
ctx.console.log(h)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const u = ctx.vfs.env.USER || 'user'
|
||||
const uid = ctx.vfs.env.UID || '1000'
|
||||
const gid = ctx.vfs.env.GID || '1000'
|
||||
const g = ctx.vfs.env.GROUP || u
|
||||
const rest = argv.slice(1)
|
||||
const wantG = rest.includes('-g') || rest.includes('--group')
|
||||
const wantU = rest.includes('-u') || rest.includes('--user')
|
||||
const wantN = rest.includes('-n') || rest.includes('--name')
|
||||
if (wantU && wantN) {
|
||||
ctx.console.log(u)
|
||||
return
|
||||
}
|
||||
if (wantG && wantN) {
|
||||
ctx.console.log(g)
|
||||
return
|
||||
}
|
||||
if (wantU) {
|
||||
ctx.console.log(uid)
|
||||
return
|
||||
}
|
||||
if (wantG) {
|
||||
ctx.console.log(gid)
|
||||
return
|
||||
}
|
||||
ctx.console.log(
|
||||
'uid=' +
|
||||
uid +
|
||||
'(' +
|
||||
u +
|
||||
') gid=' +
|
||||
gid +
|
||||
'(' +
|
||||
g +
|
||||
') groups=' +
|
||||
gid +
|
||||
'(' +
|
||||
g +
|
||||
')'
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const vfs = ctx.vfs
|
||||
const files = argv.slice(1).filter((a) => !a.startsWith('-'))
|
||||
let body = ''
|
||||
if (!files.length) {
|
||||
body = bareStdin(ctx)
|
||||
if (body === '') return
|
||||
} else {
|
||||
for (const f of files) {
|
||||
const buf = await vfs.readFile(f)
|
||||
if (!buf) {
|
||||
ctx.console.error('nl: ' + f + ': No such file')
|
||||
ctx.exitCode = 1
|
||||
continue
|
||||
}
|
||||
body += ctx.b4a.toString(buf)
|
||||
}
|
||||
}
|
||||
const lines = body.split('\n')
|
||||
if (lines.length && lines[lines.length - 1] === '') lines.pop()
|
||||
let n = 1
|
||||
for (const line of lines) {
|
||||
const num = String(n)
|
||||
const pad = ' '.repeat(Math.max(0, 6 - num.length)) + num
|
||||
ctx.console.log(pad + '\t' + line)
|
||||
n++
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const e = ctx.vfs.env
|
||||
const names = argv.slice(1).filter((a) => !a.startsWith('-'))
|
||||
if (!names.length) {
|
||||
for (const k of Object.keys(e).sort()) {
|
||||
ctx.console.log(k + '=' + (e[k] ?? ''))
|
||||
}
|
||||
return
|
||||
}
|
||||
for (const n of names) {
|
||||
if (e[n] != null) ctx.console.log(e[n])
|
||||
else ctx.exitCode = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const files = []
|
||||
let dash = false
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
const a = argv[i]
|
||||
if (dash) {
|
||||
files.push(a)
|
||||
continue
|
||||
}
|
||||
if (a === '--') {
|
||||
dash = true
|
||||
continue
|
||||
}
|
||||
if (a.startsWith('-')) continue
|
||||
files.push(a)
|
||||
}
|
||||
if (!files.length) {
|
||||
ctx.console.error('rm: missing operand')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
for (const f of files) {
|
||||
try {
|
||||
await ctx.vfs.unlink(f)
|
||||
} catch (e) {
|
||||
ctx.console.error('rm: ' + f + ': ' + (e.message || e))
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const args = argv.slice(1).filter((a) => !a.startsWith('-'))
|
||||
let a = 1
|
||||
let step = 1
|
||||
let b = 1
|
||||
if (args.length === 1) {
|
||||
b = parseInt(args[0], 10)
|
||||
} else if (args.length === 2) {
|
||||
a = parseInt(args[0], 10)
|
||||
b = parseInt(args[1], 10)
|
||||
} else if (args.length >= 3) {
|
||||
a = parseInt(args[0], 10)
|
||||
step = parseInt(args[1], 10)
|
||||
b = parseInt(args[2], 10)
|
||||
}
|
||||
if (step === 0 || Number.isNaN(a) || Number.isNaN(b) || Number.isNaN(step)) {
|
||||
ctx.console.error('seq: invalid arguments')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (step > 0) {
|
||||
for (let x = a; x <= b; x += step) ctx.console.log(String(x))
|
||||
} else {
|
||||
for (let x = a; x >= b; x += step) ctx.console.log(String(x))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const sec = parseFloat(argv[1] || '0')
|
||||
if (Number.isNaN(sec) || sec < 0) {
|
||||
ctx.console.error('sleep: invalid time interval')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
await new Promise((r) => setTimeout(r, sec * 1000))
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const vfs = ctx.vfs
|
||||
const files = argv.slice(1).filter((a) => !a.startsWith('-'))
|
||||
/** @type {string[]} */
|
||||
let lines = []
|
||||
if (!files.length) {
|
||||
const s = bareStdin(ctx)
|
||||
lines = s.length ? s.split('\n') : []
|
||||
if (lines.length && lines[lines.length - 1] === '') lines.pop()
|
||||
} else {
|
||||
for (const f of files) {
|
||||
const buf = await vfs.readFile(f)
|
||||
if (!buf) {
|
||||
ctx.console.error('sort: ' + f + ': No such file')
|
||||
ctx.exitCode = 1
|
||||
continue
|
||||
}
|
||||
const part = ctx.b4a.toString(buf).split('\n')
|
||||
if (part.length && part[part.length - 1] === '') part.pop()
|
||||
lines.push(...part)
|
||||
}
|
||||
}
|
||||
lines.sort((x, y) => (x < y ? -1 : x > y ? 1 : 0))
|
||||
if (lines.length) ctx.console.log(lines.join('\n'))
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const files = argv.slice(1).filter((a) => !a.startsWith('-'))
|
||||
if (!files.length) {
|
||||
ctx.console.error('touch: missing file operand')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
for (const f of files) {
|
||||
try {
|
||||
const existing = await ctx.vfs.readFile(f)
|
||||
await ctx.vfs.writeFile(f, existing || ctx.b4a.from(''))
|
||||
} catch (e) {
|
||||
ctx.console.error('touch: ' + f + ': ' + (e.message || e))
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
ctx.exitCode = 0
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const tty = globalThis.process?.stdout?.isTTY
|
||||
if (tty) {
|
||||
ctx.console.log('/dev/tty')
|
||||
} else {
|
||||
ctx.console.log('not a tty')
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
function joinDirFile(dir, name) {
|
||||
if (!dir || dir === '.') return name
|
||||
const d = dir.endsWith('/') ? dir.slice(0, -1) : dir
|
||||
return d + '/' + name
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const names = argv.slice(1).filter((a) => !a.startsWith('-'))
|
||||
if (!names.length) {
|
||||
ctx.console.error('which: missing argument')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
const pathEnv = ctx.vfs.env.PATH || '/bin'
|
||||
const dirs = pathEnv.split(':').filter(Boolean)
|
||||
let miss = 0
|
||||
for (const cmd of names) {
|
||||
if (cmd.includes('/')) {
|
||||
const buf = await ctx.vfs.readFile(cmd)
|
||||
if (buf != null) ctx.console.log(ctx.vfs.resolveLogical(cmd))
|
||||
else miss++
|
||||
continue
|
||||
}
|
||||
let found = false
|
||||
for (const dir of dirs) {
|
||||
const p = joinDirFile(dir, cmd)
|
||||
const buf = await ctx.drive.get(p, { follow: true })
|
||||
if (buf) {
|
||||
ctx.console.log(p)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!found) miss++
|
||||
}
|
||||
if (miss) ctx.exitCode = 1
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
ctx.console.log(ctx.vfs.env.USER || ctx.vfs.env.LOGNAME || 'user')
|
||||
}
|
||||
Reference in New Issue
Block a user