Output #

Captured text or a structured JSON result from a shell command. No symbol is added by default. Scripts run through /bin/sh -c and inherit the bar’s environment.

Configuration #

Use the item-level text template to customise or hide the label.

Set these options inside command.

PropertyDefaultDescription
showSymboltrueShow a configured or returned symbol, including an item-level override.
scriptRequiredNonblank shell script string.
timeout5Timeout in seconds, 0.1 to 60.
formattexttext or json.
outputcombined for text; stdout for JSONCapture stdout and stderr together, or stdout only. JSON rejects explicit combined.
maxLength256Integer 1 to 4096; maximum displayed characters, including the truncation ellipsis.
onErrorshowshow, keepLast, or hide.
symbols.font-Shared installed font name for configured glyph symbols; each glyph can override it.
symbols.sizeResolved item/theme font sizeShared configured glyph size, 8 to 72 points; each glyph can override it.
symbols.runningResult symbol, if retainedSymbol while the command runs.
symbols.successResult symbol, if suppliedSymbol after success.
symbols.failureRetained result symbol, if anySymbol after failure.
tints.runningResult tint, then normal tintColour while the command runs.
tints.successResult tint, then normal tintColour after success.
tints.failureRetained result tint, then normal tintColour after failure.

Text and JSON output #

Text mode captures combined stdout/stderr unless output: "stdout" is set. JSON mode always reads stdout. The bar discards stderr when it is excluded. The bar collapses whitespace and line breaks into spaces, then truncates the text to maxLength with an ellipsis. A successful command can return empty text.

For structured output, set format: "json". The script must emit one JSON object:

{
  "text": "3 updates",
  "symbol": "shippingbox.fill",
  "tint": "#FFCC00",
  "hidden": false
}
Result fieldRequiredMeaning
textYesString displayed by the item.
symbolNoSF Symbol name or complete font glyph object.
tintNo#RRGGBB or #RRGGBBAA colour.
hiddenNoBoolean controlling result visibility.

A complete command item can emit that result directly:

{
  "id": "updates",
  "type": "command",
  "command": {
    "script": "printf '%s\n' '{\"text\":\"3 updates\",\"symbol\":\"shippingbox.fill\",\"tint\":\"#FFCC00\"}'",
    "format": "json",
    "onError": "keepLast"
  }
}

Invalid JSON or invalid field values count as failures. Result data is never executed. A result glyph must include its own font, for example {"glyph":"X","font":"Menlo","size":14}.

Appearance and errors #

Symbol precedence is item-level symbol, configured state symbol, then JSON result symbol. No symbol appears if none is supplied. Configured glyphs inherit command.symbols.font and optional size, with per-glyph overrides; see font glyph symbols. SF Symbols use symbolFontWeight. showSymbol: false hides every symbol source.

Configured state tints override the result tint; otherwise the result tint applies, then normal item/theme styling. Colours accept #RRGGBB or #RRGGBBAA.

Error policyBehaviour
showDisplay the error.
keepLastRetain the last successful result; show the error if there has been no success.
hideHide the item.

Nonzero exits, timeouts, output-limit failures, and invalid JSON follow the selected policy. While a command runs again, the item shows its previous successful result with the configured running appearance. Before the first result, it shows …. A retained result keeps its JSON symbol, tint, and hidden state, subject to configured state overrides.

To change command, edit the configuration file. sbar set cannot change this block.

Shared item options cover styling, symbols, actions, priority, and enabled state.

Text templates #

The item-level text setting supports id, value, symbol, status, error. See text templates for shared fields and syntax. value keeps the command’s truncation and error policy. Templates cannot look up arbitrary JSON result fields. Result text is literal data, not a template.

status is running, success, or failure. Use state conditions to choose a label for each state.

value contains the displayed result after whitespace cleanup, truncation, and the error policy. With onError: "keepLast", a failed run retains the last successful result in value, while status is failure and error contains the new error. Before any successful run, value falls back to the error. error is empty during a new run and after success.

Use state conditions to distinguish a running check, its result, and a failure. This uses the repository-status script from the example below:

{
  "id": "repo-status",
  "type": "command",
  "symbol": "chevron.left.forwardslash.chevron.right",
  "text": "{{#status=running}}Checking\u2026{{/status}}{{#status=success}}Project: {{value}}{{/status}}{{#status=failure}}Check failed: {{error}}{{/status}}",
  "command": {
    "script": "/bin/sh \"$HOME/.config/sbar/scripts/repo-status.sh\""
  },
  "refresh": {
    "mode": "interval",
    "seconds": 60
  }
}

This displays Checking… during a run, Project: Clean or the change count after success, and an error prefixed with Check failed: after failure.

maxLength limits the result used by value, not the completed template. Literal prefixes and error can make the final label longer. An item hidden by onError: "hide" or a retained JSON result’s hidden: true stays hidden even if the template produces text.

Updates #

Commands run once at startup, including in manual mode. Item-ID triggers rerun them even without a refresh configuration; named refresh events also trigger runs. The bar combines triggers received within 50 milliseconds and replaces any running command.

Interval delays begin after completion; a trigger restarts that schedule. Changes to the script, timeout, output selection, format, or refresh settings rerun the command. Changing maxLength, onError, symbols, tints, or the item-level text changes how the result appears without rerunning the script. See refresh policies.

Current limits #

Captured output is limited to 64 KB; exceeding that limit fails the run. This is separate from maxLength, which truncates displayed result text without failing the command. Scripts receive no interactive input because stdin is connected to /dev/null. Timeout, cancellation, and completion terminate the process group. Commands display their output after they finish. Use a process plugin for streamed output.

Example #

Keep an eye on uncommitted changes in a local Git repository. Save this script as ~/.config/sbar/scripts/repo-status.sh, creating the scripts directory if needed:

repo="$HOME/Code/my-project"
changes=$(git -C "$repo" status --porcelain --untracked-files=all) || exit $?
if [ -z "$changes" ]; then
  printf 'Clean\n'
else
  count=$(printf '%s\n' "$changes" | awk 'END { print NR }')
  printf '%s changes\n' "$count"
fi

Replace $HOME/Code/my-project with the repository path. Then add this item:

{
  "id": "repo-status",
  "type": "command",
  "symbol": "chevron.left.forwardslash.chevron.right",
  "text": "Project: {{value}}",
  "command": {
    "script": "/bin/sh \"$HOME/.config/sbar/scripts/repo-status.sh\"",
    "tints": {
      "failure": "#FF6655"
    }
  },
  "refresh": {
    "mode": "interval",
    "seconds": 60
  }
}

The item displays Project: Clean or a count such as Project: 3 changes. It counts Git status entries, including staged, unstaged, and untracked files. A file changed in both the index and working tree counts once. It does not count changed lines or check the remote repository.

The command runs at startup and waits 60 seconds after each run before checking again. Read failures remain visible in red. Change the Project: prefix to your repository’s name. The script runs through /bin/sh, so it does not need executable permissions.

After a commit, request an immediate update:

sbar trigger repo-status

Search docs

Enter a word or command.