โ† All skills
Tencent SkillHub ยท Developer Tools

Shell Scripting

Write robust, portable shell scripts. Use when parsing arguments, handling errors properly, writing POSIX-compatible scripts, managing temp files, running commands in parallel, managing background processes, or adding --help to scripts.

skill openclawclawhub Free
0 Downloads
0 Stars
0 Installs
0 Score
High Signal

Write robust, portable shell scripts. Use when parsing arguments, handling errors properly, writing POSIX-compatible scripts, managing temp files, running commands in parallel, managing background processes, or adding --help to scripts.

โฌ‡ 0 downloads โ˜… 0 stars Unverified but indexed

Install for OpenClaw

Quick setup
  1. Download the package from Yavira.
  2. Extract the archive and review SKILL.md first.
  3. Import or place the package into your OpenClaw setup.

Requirements

Target platform
OpenClaw
Install method
Manual import
Extraction
Extract archive
Prerequisites
OpenClaw
Primary doc
SKILL.md

Package facts

Download mode
Yavira redirect
Package format
ZIP package
Source platform
Tencent SkillHub
What's included
SKILL.md

Validation

  • Use the Yavira download entry.
  • Review SKILL.md after the package is downloaded.
  • Confirm the extracted package contains the expected setup assets.

Install with your agent

Agent handoff

Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.

  1. Download the package from Yavira.
  2. Extract it into a folder your agent can access.
  3. Paste one of the prompts below and point your agent at the extracted folder.
New install

I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.

Upgrade existing

I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.

Trust & source

Release facts

Source
Tencent SkillHub
Verification
Indexed source record
Version
1.0.0

Documentation

ClawHub primary doc Primary doc: SKILL.md 24 sections Open source page

Shell Scripting

Write reliable, maintainable bash scripts. Covers argument parsing, error handling, portability, temp files, parallel execution, process management, and self-documenting scripts.

When to Use

Writing scripts that others (or future you) will run Automating multi-step workflows Parsing command-line arguments with flags and options Handling errors and cleanup properly Running tasks in parallel Making scripts portable across Linux and macOS Wrapping complex commands with a simpler interface

Script Template

#!/usr/bin/env bash set -euo pipefail # Description: What this script does (one line) # Usage: script.sh [options] <required-arg> readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" readonly SCRIPT_NAME="$(basename "$0")" # Defaults VERBOSE=false OUTPUT_DIR="./output" usage() { cat <<EOF Usage: $SCRIPT_NAME [options] <input-file> Description: Process the input file and generate output. Options: -o, --output DIR Output directory (default: $OUTPUT_DIR) -v, --verbose Enable verbose output -h, --help Show this help message Examples: $SCRIPT_NAME data.csv $SCRIPT_NAME -v -o /tmp/results data.csv EOF } log() { echo "[$(date '+%H:%M:%S')] $*" >&2; } debug() { $VERBOSE && log "DEBUG: $*" || true; } die() { log "ERROR: $*"; exit 1; } # Parse arguments while [[ $# -gt 0 ]]; do case "$1" in -o|--output) OUTPUT_DIR="$2"; shift 2 ;; -v|--verbose) VERBOSE=true; shift ;; -h|--help) usage; exit 0 ;; --) shift; break ;; -*) die "Unknown option: $1" ;; *) break ;; esac done INPUT_FILE="${1:?$(usage >&2; echo "Error: input file required")}" [[ -f "$INPUT_FILE" ]] || die "File not found: $INPUT_FILE" # Main logic main() { debug "Input: $INPUT_FILE" debug "Output: $OUTPUT_DIR" mkdir -p "$OUTPUT_DIR" log "Processing $INPUT_FILE..." # ... do work ... log "Done. Output in $OUTPUT_DIR" } main "$@"

set flags

set -e # Exit on any command failure set -u # Error on undefined variables set -o pipefail # Pipe fails if any command in the pipe fails set -x # Debug: print each command before executing (noisy) # Combined (use this in every script) set -euo pipefail # Temporarily disable for commands that are allowed to fail set +e some_command_that_might_fail exit_code=$? set -e

Trap for cleanup

# Cleanup on exit (any exit: success, failure, or signal) TMPDIR="" cleanup() { [[ -n "$TMPDIR" ]] && rm -rf "$TMPDIR" } trap cleanup EXIT TMPDIR=$(mktemp -d) # Use $TMPDIR freely โ€” it's cleaned up automatically # Trap specific signals trap 'echo "Interrupted"; exit 130' INT # Ctrl+C trap 'echo "Terminated"; exit 143' TERM # kill

Error handling patterns

# Check command exists before using it command -v jq >/dev/null 2>&1 || die "jq is required but not installed" # Provide default values NAME="${NAME:-default_value}" # Required variable (fail if unset) : "${API_KEY:?Error: API_KEY environment variable is required}" # Retry a command retry() { local max_attempts=$1 shift local attempt=1 while [[ $attempt -le $max_attempts ]]; do "$@" && return 0 log "Attempt $attempt/$max_attempts failed. Retrying..." ((attempt++)) sleep $((attempt * 2)) done die "Command failed after $max_attempts attempts: $*" } retry 3 curl -sf https://api.example.com/health

Simple: positional + flags

# Manual parsing (no dependencies) FORCE=false DRY_RUN=false while [[ $# -gt 0 ]]; do case "$1" in -f|--force) FORCE=true; shift ;; -n|--dry-run) DRY_RUN=true; shift ;; -o|--output) [[ -n "${2:-}" ]] || die "--output requires a value" OUTPUT="$2"; shift 2 ;; --output=*) OUTPUT="${1#*=}"; shift ;; -h|--help) usage; exit 0 ;; --) shift; break ;; # End of options -*) die "Unknown option: $1" ;; *) break ;; # Start of positional args esac done # Remaining args are positional FILES=("$@") [[ ${#FILES[@]} -gt 0 ]] || die "At least one file is required"

getopts (POSIX, short options only)

while getopts ":o:vhf" opt; do case "$opt" in o) OUTPUT="$OPTARG" ;; v) VERBOSE=true ;; f) FORCE=true ;; h) usage; exit 0 ;; :) die "Option -$OPTARG requires an argument" ;; ?) die "Unknown option: -$OPTARG" ;; esac done shift $((OPTIND - 1))

Temp Files and Directories

# Create temp file (automatically unique) TMPFILE=$(mktemp) echo "data" > "$TMPFILE" # Create temp directory TMPDIR=$(mktemp -d) # Create temp with custom prefix/suffix TMPFILE=$(mktemp /tmp/myapp.XXXXXX) TMPFILE=$(mktemp --suffix=.json) # GNU only # Always clean up with trap trap 'rm -f "$TMPFILE"' EXIT # Portable pattern (works on macOS and Linux) TMPDIR=$(mktemp -d 2>/dev/null || mktemp -d -t 'myapp') trap 'rm -rf "$TMPDIR"' EXIT

xargs -P

# Run 4 commands in parallel cat urls.txt | xargs -P 4 -I {} curl -sO {} # Process files in parallel (4 at a time) find . -name "*.csv" | xargs -P 4 -I {} ./process.sh {} # Parallel with progress indicator find . -name "*.jpg" | xargs -P 8 -I {} sh -c 'convert {} -resize 800x600 resized/{} && echo "Done: {}"'

Background jobs + wait

# Run tasks in background, wait for all pids=() for file in data/*.csv; do process_file "$file" & pids+=($!) done # Wait for all and check results failed=0 for pid in "${pids[@]}"; do wait "$pid" || ((failed++)) done [[ $failed -eq 0 ]] || die "$failed jobs failed"

GNU Parallel (if available)

# Process files with 8 parallel jobs parallel -j 8 ./process.sh {} ::: data/*.csv # With progress bar parallel --bar -j 4 convert {} -resize 800x600 resized/{/} ::: *.jpg # Pipe input lines cat urls.txt | parallel -j 10 curl -sO {}

Background processes

# Start in background long_running_command & BG_PID=$! # Check if still running kill -0 $BG_PID 2>/dev/null && echo "Running" || echo "Stopped" # Wait for it wait $BG_PID echo "Exit code: $?" # Kill on script exit trap 'kill $BG_PID 2>/dev/null' EXIT

Process supervision

# Run a command, restart if it dies run_with_restart() { local cmd=("$@") while true; do "${cmd[@]}" & local pid=$! log "Started PID $pid" wait $pid local exit_code=$? log "Process exited with code $exit_code. Restarting in 5s..." sleep 5 done } run_with_restart ./my-server --port 8080

Timeout

# Kill command after 30 seconds timeout 30 long_running_command # With custom signal (SIGKILL after SIGTERM fails) timeout --signal=TERM --kill-after=10 30 long_running_command # Portable (no timeout command) ( sleep 30; kill $$ 2>/dev/null ) & TIMER_PID=$! long_running_command kill $TIMER_PID 2>/dev/null

Common differences

# sed: macOS requires -i '' (empty backup extension) # Linux: sed -i 's/old/new/g' file.txt # macOS: sed -i '' 's/old/new/g' file.txt # Portable: sed -i.bak 's/old/new/g' file.txt && rm file.txt.bak # date: different flags # GNU (Linux): date -d '2026-02-03' '+%s' # BSD (macOS): date -j -f '%Y-%m-%d' '2026-02-03' '+%s' # readlink -f: doesn't exist on macOS # Portable alternative: real_path() { cd "$(dirname "$1")" && echo "$(pwd)/$(basename "$1")"; } # stat: different syntax # GNU: stat -c '%s' file # BSD: stat -f '%z' file # grep -P: not available on macOS by default # Use grep -E instead, or install GNU grep

POSIX-safe patterns

# Use printf instead of echo -e (echo behavior varies) printf "Line 1\nLine 2\n" # Use $() instead of backticks result=$(command) # Good result=`command` # Bad (deprecated, nesting issues) # Use [[ ]] for tests (bash), [ ] for POSIX sh [[ -f "$file" ]] # Bash (safer, no word splitting) [ -f "$file" ] # POSIX sh # Array check (bash only, not POSIX) if [[ ${#array[@]} -gt 0 ]]; then echo "Array has elements" fi

Source a config file

# Simple: source a key=value file # config.env: # DB_HOST=localhost # DB_PORT=5432 # Validate before sourcing (security: check for commands) if grep -qP '^[A-Z_]+=.*[;\`\$\(]' config.env; then die "Config file contains unsafe characters" fi source config.env

Parse INI-style config

# config.ini: # [database] # host = localhost # port = 5432 # [app] # debug = true parse_ini() { local file="$1" section="" while IFS='= ' read -r key value; do [[ -z "$key" || "$key" =~ ^[#\;] ]] && continue if [[ "$key" =~ ^\[(.+)\]$ ]]; then section="${BASH_REMATCH[1]}" continue fi value="${value%%#*}" # Strip inline comments value="${value%"${value##*[![:space:]]}"}" # Trim trailing whitespace printf -v "${section}_${key}" '%s' "$value" done < "$file" } parse_ini config.ini echo "$database_host" # localhost echo "$app_debug" # true

Confirm before destructive action

confirm() { local prompt="${1:-Are you sure?}" read -rp "$prompt [y/N] " response [[ "$response" =~ ^[Yy]$ ]] } confirm "Delete all files in /tmp/data?" || die "Aborted" rm -rf /tmp/data/*

Progress indicator

# Simple counter total=$(wc -l < file_list.txt) count=0 while IFS= read -r file; do ((count++)) printf "\rProcessing %d/%d..." "$count" "$total" >&2 process "$file" done < file_list.txt echo "" >&2

Lock file (prevent concurrent runs)

LOCKFILE="/tmp/${SCRIPT_NAME}.lock" acquire_lock() { if ! mkdir "$LOCKFILE" 2>/dev/null; then die "Another instance is running (lock: $LOCKFILE)" fi trap 'rm -rf "$LOCKFILE"' EXIT } acquire_lock # ... safe to proceed, only one instance runs ...

Stdin or file argument

# Read from file argument or stdin input="${1:--}" # Default to "-" (stdin) if [[ "$input" == "-" ]]; then cat else cat "$input" fi | while IFS= read -r line; do process "$line" done

Tips

Always start with set -euo pipefail. It catches 80% of silent bugs. Always use trap cleanup EXIT for temp files. Never rely on reaching the cleanup code at the end. Quote all variable expansions: "$var" not $var. Unquoted variables break on spaces and globs. Use [[ ]] instead of [ ] in bash. It handles empty strings, spaces, and pattern matching better. shellcheck is the best linter for shell scripts. Run it: shellcheck myscript.sh. Install it if available. readonly for constants prevents accidental overwrite: readonly DB_HOST="localhost". Write a usage() function and call it on -h/--help and on missing required arguments. Future users (including you) will thank you. Prefer printf over echo for anything that might contain special characters or needs formatting. Test scripts with bash -n script.sh (syntax check) before running.

Category context

Code helpers, APIs, CLIs, browser automation, testing, and developer operations.

Source: Tencent SkillHub

Largest current source with strong distribution and engagement signals.

Package contents

Included in package
1 Docs
  • SKILL.md Primary doc