Skip to content

just-bash@3.6.0

Choose a tag to compare

@github-actions github-actions released this 01 Oct 12:41
· 11 commits to main since this release
7537a26

Minor Changes

  • #377 cc35fab Thanks @trieloff! - Add the mktemp command. It creates a unique temporary file (mode 0600) or directory (-d, mode 0700) and prints its path, supporting -p/--tmpdir[=DIR], -t, -u/--dry-run, -q/--quiet, --suffix=SUFF, GNU-style TEMPLATE expansion, --help and --version. The default directory is $TMPDIR when set and non-empty, otherwise /tmp, so sandboxed embedders that point TMPDIR at a writable directory get a usable path. Random name characters come from the platform CSPRNG (crypto.getRandomValues), and existing paths are never returned.

    Adds an optional createExclusive(path, { mode, directory }) method to IFileSystem, which creates an entry only if the name is free and applies the mode at creation time rather than via a follow-up chmod. All built-in filesystems implement it. The member is optional, so external IFileSystem implementations remain source compatible; mktemp reports that such a filesystem cannot create atomically rather than substituting a non-atomic sequence. The accompanying CreateExclusiveOptions type is exported alongside the existing MkdirOptions/RmOptions.

  • #409 5d19cc3 Thanks @trieloff! - Add the yes command. yes [STRING]... repeats a line built from its operands (y when there are none), so yes | head -3 and yes | some-prompt work instead of failing with exit 127. Because pipeline stages here run to completion rather than streaming, the stream is finite: it ends after executionLimits.maxLoopIterations lines, or earlier if the repeated line would exceed the output size limit.

Patch Changes

  • #445 7313062 Thanks @trieloff! - interpreter: preserve complete associative-array values in declare -A compound assignments

    Quoted values containing whitespace were reconstructed without quoting before the declare builtin parsed them, so every value was silently truncated at its first space. Associative-array declarations now retain whitespace and other quoted content.

  • #346 52a5617 Thanks @iroiro147! - fs: keep the Buffer-less fromBuffer fallback under the argument limit

    Without Buffer (for example in a Chrome extension service worker), fromBuffer converted base64, binary and latin1 content by spreading 64KB chunks into String.fromCharCode, which can exceed the engine's argument limit and throw RangeError: Maximum call stack size exceeded on a 64KB cat. The fallback now converts in 8KB chunks.

  • #443 a36c324 Thanks @RyanGarber! - Handle accessor descriptors when installing module defense-in-depth proxies on Bun, preserving blocking behavior and original descriptors on teardown.

  • #414 31ac823 Thanks @mutewinter! - find: report a directory it cannot read and keep going

    A readdir failure inside the traversal threw out of the whole search, so one unreadable directory ended find with no results: exit 1 and find: EACCES: permission denied, scandir '<path>' on its own, and exit 0 with nothing at all once piped through head with stderr silenced. Every macOS home directory holds such a directory (.Trash, several under Library), so a recursive find over a mounted home directory never returned anything.

    GNU find names the directory on stderr, continues with everything else, and exits 1 at the end. It now does the same here. The message is find: <path>: Permission denied, with the phrase taken from the errno alone, so nothing from the underlying error's text reaches the output. A failure that is not one of the errnos a directory read can produce (a cancellation, an execution limit, a filesystem policy refusal) still ends the search as before.

    Messages are emitted in traversal order beside the node's own output, whatever order the parallel batch settled in, and a failed read still counts toward the trace's readdirCalls and readdirTime.

  • #384 e0cca16 Thanks @taoche! - Match real jq behavior for to_entries on arrays (numeric-key entries instead of null) and tonumber on empty or whitespace-only strings (error instead of 0).

  • #417 017a911 Thanks @trieloff! - interpreter: give a loop left via break/continue status 0 instead of the last command's

    break and continue are builtins that return 0, and they are the last command a loop body runs. A loop exited through them reported the status of whatever ran before the break instead:

    while :; do false; break; done; echo $?            # was 1, bash says 0
    for i in 1; do false; break; done; echo $?         # was 1, bash says 0
    for i in 1 2; do false; continue; done; echo $?    # was 1, bash says 0

    All four loop forms were affected — for, C-style for, while, until — as was a break/continue in a while condition and a multi-level break 2 unwinding through an enclosing loop.

    The stale status is invisible until something reads $?, and under set -e the phantom failing loop ends the script with no output and no diagnostic:

    set -euo pipefail
    while :; do
      [ 5 -eq 0 ] && break     # correctly exempt from errexit as the left operand of &&
      break
    done
    echo ok                    # never ran

    $? moves with the status, so the next iteration sees it too — a for loop runs nothing between the continue and the next iteration's first command, and would otherwise still expose the failure there:

    for i in 1 2; do echo "$i:$?"; false; continue; done   # was 1:0 2:1, bash says 1:0 2:0

    continue sets the status at the point it runs but does not pin it: a later iteration still overwrites it, so for i in 1 2; do if [ $i = 1 ]; then true; continue; fi; false; done is still 1. A loop that ends normally is unchanged and reports its last command, and return from a function still reports the last command rather than 0.

    Reported downstream as ai-ecoverse/slicc#2978.

  • #488 c21d678 Thanks @FredAmartey! - Give MountableFs synchronous mkdirSync and writeFileSync, routed to the filesystem that owns the path, so Bash sets up /bin, /dev, /proc, /tmp and the working directory in its base. Paths on a filesystem without synchronous writes throw ENOSYS and are left out of the layout.

  • #416 4af0dc0 Thanks @trieloff! - Fix default, assignment, and alternative parameter expansions used as an entire double-quoted word under set -u. For example, echo "${U:-fallback}" now prints fallback when U is unset instead of reporting "unbound variable". This also lets scripts safely check optional CI variables such as GITHUB_STEP_SUMMARY.

  • #509 632090a Thanks @janneh! - Bundle the patched smol-toml 1.9.0.

    The Node bundle inlines smol-toml, so a consumer can't pick up its fix through its own lockfile. Only a just-bash release carries it.

  • #444 128feaa Thanks @RyanGarber! - Use a virtual executable name for CPython instead of the host worker path, avoiding script finalization failures under long installation paths without weakening worker protections.

  • #314 90df057 Thanks @tylergibbs1! - Repeated grep -e options overwrote the earlier patterns, so only the last one was used. All -e patterns now combine.

  • #503 130da94 Thanks @asafyish! - Host operations that settle after a cancelled execution no longer surface as a process-level unhandledRejection.

    Aborting or timing out an execution while the worker bridge was awaiting a host tool (or an exec) left that operation to settle after the defense-in-depth box deactivated. The box's Promise.prototype.then guard, which blocks sandbox callbacks once their execution ends, then dropped the handlers meant to consume that result: a late rejection crashed processes that treat unhandled rejections as fatal, and a late success never reached the bridge. Host-side settlement now goes through await, which bypasses the guarded then.

  • #487 0353b22 Thanks @FredAmartey! - Keep leading blanks after a\, i\ and c\ in sed text, as GNU does, including blanks escaped with a backslash. The one-line a text form now strips every leading blank instead of only the first.

  • #513 ef8c75d Thanks @jamalkamaladdin! - Fix intermittent python3 failures with OSError: [Errno 29] I/O error on a busy host. A wakeup left over from the previous bridge call could end the wait for the next call before the main thread answered it. The worker now keeps waiting until the call is answered, within the same operation timeout.

  • #506 4ee035b Thanks @privatenumber! - timeout: a deadline that lands while a command is still loading no longer aborts the rest of the script

    timeout on a cold command — the first use of any lazily loaded command — could return 124 and still kill every statement after it. Cancelled invocations now stop waiting for the load and report cancellation instead.