playbook/outfitter-agents/plugins/outfitter/skills/claude-commands/references/bash-execution.md

6.2 KiB

Bash Execution Reference

Complete guide to executing shell commands within Claude Code slash commands.

Overview

The ! prefix executes bash commands and includes their output in the command context before Claude processes it.

Current branch: !`git branch --show-current`

Syntax

Basic Execution

!`command here`

The command runs, and output replaces the !backtick block.

Examples

## Git Context
Branch: !`git branch --show-current`
Status: !`git status --short`
User: !`git config user.email`

Output (example):

## Git Context
Branch: main
Status: M  src/app.ts
?? new-file.ts
User: developer@example.com

Command Types

Simple Commands

Current directory: !`pwd`
Node version: !`node --version`
Current user: !`whoami`
Date: !`date +%Y-%m-%d`

Pipelines

Recent authors:
!`git log --format='%an' -20 | sort | uniq -c | sort -rn`

TypeScript files:
!`find src -name '*.ts' | wc -l`

Large files:
!`find . -type f -size +1M | head -10`

Complex Commands

Test results:
!`bun test --reporter=json 2>&1 | jq '.summary'`

Open PRs:
!`gh pr list --limit 5 --json number,title,author | jq '.[] | "\(.number): \(.title) by \(.author.login)"'`

Code stats:
!`git diff --stat HEAD~10..HEAD | tail -3`

Multi-line Commands

Environment check:
!`echo "Node: $(node --version)"
echo "npm: $(npm --version)"
echo "bun: $(bun --version 2>/dev/null || echo 'not installed')"`

Output Handling

Character Budget

Default limit: 15,000 characters per command

Configure via environment variable:

export SLASH_COMMAND_TOOL_CHAR_BUDGET=30000

Exceeding budget:

  • Output truncated with warning
  • Command still executes
  • Consider limiting output in command

Limiting Output

# Limit lines
Recent commits: !`git log --oneline -10`

# Truncate with head
Large output: !`cat big-file.txt | head -50`

# Filter relevant lines
Errors only: !`bun test 2>&1 | grep -E "FAIL|Error"`

# Summary instead of full
Stats only: !`git diff --stat | tail -1`

Error Handling

Stderr is captured:

Result: !`some-command 2>&1`

Conditional execution:

Status: !`git status 2>&1 || echo "Not a git repository"`

File check: !`[ -f config.json ] && cat config.json || echo "No config found"`

Exit codes:

Test result:
!`bun test && echo "All tests passed" || echo "Tests failed"`

Patterns

Git Workflows

## Repository State

Branch: !`git branch --show-current`
Commits ahead: !`git rev-list --count origin/main..HEAD`
Last commit: !`git log -1 --format='%h %s (%ar)'`

## Changes

Staged: !`git diff --staged --stat`
Unstaged: !`git diff --stat`
Untracked: !`git ls-files --others --exclude-standard`

Project Analysis

## Project Structure

!`tree -L 2 -I 'node_modules|.git' 2>/dev/null || find . -maxdepth 2 -type d | head -20`

## Dependencies

!`cat package.json | jq '.dependencies | keys | length'` dependencies
!`cat package.json | jq '.devDependencies | keys | length'` dev dependencies

## Scripts

!`cat package.json | jq -r '.scripts | to_entries[] | "- \(.key): \(.value)"'`

GitHub Integration

## Issue Details

!`gh issue view $1 --json title,body,labels,assignees | jq -r '
  "Title: \(.title)\n" +
  "Labels: \(.labels | map(.name) | join(", "))\n" +
  "Assignees: \(.assignees | map(.login) | join(", "))\n\n" +
  "Body:\n\(.body)"
'`

## Recent PRs

!`gh pr list --limit 5 --json number,title,state | jq -r '.[] | "#\(.number) [\(.state)] \(.title)"'`

Environment Validation

## Prerequisites

Node: !`node --version 2>&1 || echo "NOT INSTALLED"`
Docker: !`docker --version 2>&1 || echo "NOT INSTALLED"`
kubectl: !`kubectl version --client --short 2>&1 || echo "NOT INSTALLED"`

## Configuration

AWS: !`aws sts get-caller-identity --query Account 2>&1 || echo "Not configured"`

Arguments in Bash

Use command arguments in shell commands:

---
argument-hint: <file-path>
---

## File Info

Path: $1
Size: !`ls -lh "$1" | awk '{print $5}'`
Lines: !`wc -l < "$1"`
Type: !`file "$1"`

## Content Preview

!`head -20 "$1"`

Important: Quote arguments to handle spaces:

!`cat "$1"`      # Correct
!`cat $1`        # Breaks with spaces in path

Conditional Logic

If/Else

## Environment Check

!`if [ "$1" = "production" ]; then
  echo "WARNING: Production deployment"
  echo "Requires additional approval"
else
  echo "Environment: $1"
  echo "Ready to proceed"
fi`

Case Statements

## Action Selection

!`case "$1" in
  deploy)
    echo "Deploying..."
    ;;
  rollback)
    echo "Rolling back..."
    ;;
  status)
    echo "Checking status..."
    ;;
  *)
    echo "Unknown action: $1"
    echo "Valid: deploy, rollback, status"
    ;;
esac`

Security Considerations

Avoid Command Injection

# Dangerous - user input directly in command
!`cat $1`

# Safer - validate input first
!`[[ "$1" =~ ^[a-zA-Z0-9_/-]+\.ts$ ]] && cat "$1" || echo "Invalid file path"`

Read-Only Commands

Use allowed-tools to restrict capabilities:

---
allowed-tools: Bash(git show:*), Bash(git diff:*), Bash(git log:*), Read
---

Limit Destructive Operations

---
description: Safe code review
allowed-tools: Read, Grep, Glob
---

# No bash execution - read-only review

Common Errors

Missing Backticks

# Wrong
!git status

# Correct
!`git status`

Broken Quotes

# Wrong (unbalanced quotes)
!`echo "Hello`

# Correct
!`echo "Hello"`

Unsafe Variable Expansion

# Wrong (no quotes)
!`cat $1`

# Correct (quoted)
!`cat "$1"`

Exceeding Output Limit

# Wrong (huge output)
!`cat very-large-file.log`

# Correct (limited)
!`tail -100 very-large-file.log`

Best Practices

  1. Test commands in terminal first
  2. Quote all variables for safety
  3. Limit output to relevant portions
  4. Handle errors with 2>&1 or ||
  5. Use allowed-tools to restrict access
  6. Validate arguments before using in commands
  7. Provide context about what commands do