Skip to main content

shell-bash

Shell scripting and Bash programming patterns

Quellinformationen

Repository
miles990/claude-software-skills
Letzte Quellaktivität
8. Januar 2026 um 02:34
Erkannte Sprache von SKILL.md
Englisch
Sterne
26
Forks
6

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
3 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
shell-bash
description
Shell scripting and Bash programming patterns
domain
programming-languages
version
1.0.0
tags
["bash","shell","scripting","automation","cli"]
triggers
{"keywords":{"primary":["bash","shell","sh","zsh","script","terminal","cli"],"secondary":["grep","sed","awk","pipe","cron","automation","makefile"]},"context_boost":["devops","linux","unix","automation","sysadmin"],"context_penalty":["web","frontend","mobile","gui"],"priority":"medium"}
# Shell & Bash Scripting ## Overview Shell scripting patterns for automation, system administration, and CLI tools. --- ## Script Fundamentals ### Script Structure ```bash #!/usr/bin/env bash # # Script: backup.sh # Description: Backup files to remote server # Usage: ./backup.sh [options] <source> <destination> # set -euo pipefail # Exit on error, undefined vars, pipe failures IFS=$'\n\t' # Safer word splitting # Constants readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")" readonly LOG_FILE="/var/log/${SCRIPT_NAME%.sh}.log" # Default values VERBOSE=false DRY_RUN=false COMPRESS=true # Cleanup on exit cleanup() { local exit_code=$? # Cleanup temporary files rm -f "${TEMP_FILE:-}" exit "$exit_code" } trap cleanup EXIT # Logging functions log() { local level="$1" shift echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*" | tee -a "$LOG_FILE" } info() { log "INFO" "$@"; } warn() { log "WARN" "$@" >&2; } error() { log "ERROR" "$@" >&2; } debug() { [[ "$VERBOSE" == true ]] && log "DEBUG" "$@" || true; } die() { error "$@" exit 1 } # Usage usage() { cat <<EOF Usage: $SCRIPT_NAME [options] <source> <destination> Options: -v, --verbose Enable verbose output -n, --dry-run Show what would be done -h, --help Show this help message Examples: $SCRIPT_NAME /data /backup $SCRIPT_NAME -v --dry-run /home/user /mnt/backup EOF } # Main function main() { parse_args "$@" validate_inputs perform_backup } # Run main if script is executed directly if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi ``` ### Argument Parsing ```bash # Using getopts (POSIX) parse_args_getopts() { while getopts ":vnh" opt; do case $opt in v) VERBOSE=true ;; n) DRY_RUN=true ;; h) usage; exit 0 ;; \?) die "Invalid option: -$OPTARG" ;; :) die "Option -$OPTARG requires an argument" ;; esac done shift $((OPTIND - 1)) SOURCE="${1:-}" DESTINATION="${2:-}" } # Using manual parsing (supports long options) parse_args() { while [[ $# -gt 0 ]]; do case "$1" in -v|--verbose) VERBOSE=true shift ;; -n|--dry-run) DRY_RUN=true shift ;; -c|--compress) COMPRESS=true shift ;; --no-compress) COMPRESS=false shift ;; -h|--help) usage exit 0 ;; --) shift break ;; -*) die "Unknown option: $1" ;; *) break ;; esac done # Positional arguments SOURCE="${1:-}" DESTINATION="${2:-}" } # Validation validate_inputs() { [[ -z "$SOURCE" ]] && die "Source path is required" [[ -z "$DESTINATION" ]] && die "Destination path is required" [[ -e "$SOURCE" ]] || die "Source does not exist: $SOURCE" } ``` --- ## Variables and Data ### Variable Operations ```bash # Variable assignment name="John" readonly CONSTANT="immutable" # Default values name="${name:-default}" # Use default if unset or empty name="${name:=default}" # Assign default if unset or empty name="${name:+alternative}" # Use alternative if set and non-empty name="${name:?error message}" # Error if unset or empty # String manipulation str="Hello, World!" echo "${str:0:5}" # "Hello" (substring) echo "${str: -6}" # "World!" (last 6 chars) echo "${#str}" # 13 (length) echo "${str/World/Bash}" # "Hello, Bash!" (replace first) echo "${str//o/0}" # "Hell0, W0rld!" (replace all) echo "${str#Hello, }" # "World!" (remove prefix) echo "${str%!}" # "Hello, World" (remove suffix) echo "${str^^}" # "HELLO, WORLD!" (uppercase) echo "${str,,}" # "hello, world!" (lowercase) # Parameter expansion filename="/path/to/file.tar.gz" echo "${filename##*/}" # "file.tar.gz" (basename) echo "${filename%/*}" # "/path/to" (dirname) echo "${filename%%.*}" # "/path/to/file" (remove all extensions) echo "${filename%.gz}" # "/path/to/file.tar" (remove last extension) ``` ### Arrays ```bash # Indexed arrays declare -a fruits=("apple" "banana" "cherry") fruits+=("date") # Append echo "${fruits[0]}" # "apple" (first element) echo "${fruits[-1]}" # "date" (last element) echo "${fruits[@]}" # All elements echo "${#fruits[@]}" # 4 (length) echo "${!fruits[@]}" # 0 1 2 3 (indices) # Iterate for fruit in "${fruits[@]}"; do echo "$fruit" done # With indices for i in "${!fruits[@]}"; do echo "$i: ${fruits[i]}" done # Associative arrays (bash 4+) declare -A user=( [name]="John" [email]="john@example.com" [age]=30 ) echo "${user[name]}" # "John" echo "${!user[@]}" # Keys: name email age echo "${user[@]}" # Values # Iterate key-value for key in "${!user[@]}"; do echo "$key: ${user[$key]}" done # Array slicing echo "${fruits[@]:1:2}" # "banana" "cherry" (from index 1, 2 elements) # Array filtering (bash 4+) evens=() for n in "${numbers[@]}"; do (( n % 2 == 0 )) && evens+=("$n") done ``` --- ## Control Flow ### Conditionals ```bash # Test operators # Strings [[ -z "$str" ]] # Empty [[ -n "$str" ]] # Not empty [[ "$a" == "$b" ]] # Equal [[ "$a" != "$b" ]] # Not equal [[ "$a" < "$b" ]] # Less than (lexicographic) [[ "$a" =~ ^[0-9]+$ ]] # Regex match # Numbers [[ "$a" -eq "$b" ]] # Equal [[ "$a" -ne "$b" ]] # Not equal [[ "$a" -lt "$b" ]] # Less than [[ "$a" -le "$b" ]] # Less than or equal [[ "$a" -gt "$b" ]] # Greater than [[ "$a" -ge "$b" ]] # Greater than or equal # Files [[ -e "$file" ]] # Exists [[ -f "$file" ]] # Regular file [[ -d "$dir" ]] # Directory [[ -r "$file" ]] # Readable [[ -w "$file" ]] # Writable [[ -x "$file" ]] # Executable [[ -s "$file" ]] # Size > 0 [[ "$a" -nt "$b" ]] # Newer than [[ "$a" -ot "$b" ]] # Older than # If-elif-else if [[ "$status" == "success" ]]; then echo "Success!" elif [[ "$status" == "pending" ]]; then echo "Still pending..." else echo "Failed" fi # Case statement case "$command" in start|begin) start_service ;; stop|end) stop_service ;; restart) stop_service start_service ;; *) echo "Unknown command: $command" exit 1 ;; esac # Short-circuit [[ -f "$file" ]] && process_file "$file" [[ -d "$dir" ]] || mkdir -p "$dir" ``` ### Loops ```bash # For loop for item in item1 item2 item3; do echo "$item" done # C-style for for ((i = 0; i < 10; i++)); do echo "$i" done # While loop counter=0 while [[ $counter -lt 5 ]]; do echo "$counter" ((counter++)) done # Read file line by line while IFS= read -r line; do echo "$line" done < "$file" # Process command output while IFS= read -r file; do echo "Processing: $file" done < <(find . -name "*.txt") # Until loop until [[ -f "$lockfile" ]]; do sleep 1 done # Break and continue for i in {1..10}; do [[ $i -eq 5 ]] && continue [[ $i -eq 8 ]] && break echo "$i" done ``` --- ## Functions ```bash # Basic function greet() { local name="$1" echo "Hello, $name!" } # Function with return value is_valid_email() { local email="$1" [[ "$email" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]] } # Check return value if is_valid_email "test@example.com"; then echo "Valid email" fi # Function with output capture get_user_count() { wc -l < /etc/passwd } count=$(get_user_count) # Function with array parameter process_files() { local -a files=("$@")
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen