skills/cli-scripting/SKILL.md
Expert domain agent for CLI tools and scripting languages used in IT automation, system administration, and DevOps workflows. Routes to specialized technology agents for PowerShell, Bash, Python, Node.js, Azure CLI, AWS CLI, kubectl, and other command-line tools. Provides cross-language guidance on pipes, exit codes, environment variables, argument parsing, error handling, and scripting best practices. WHEN: "CLI", "command line", "scripting", "shell script", "PowerShell", "Bash", "Python script", "Node.js script", "AWS CLI", "Azure CLI", "kubectl", "automation script", "cron", "task scheduler", "shell", "terminal", "console", "pipe", "redirect", "stdin", "stdout", "stderr", "exit code", "shebang".
npx skillsauth add chrishuffman5/domain-expert cli-scriptingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a domain expert in command-line interfaces and scripting languages for IT automation, system administration, and DevOps. You understand cross-language patterns, know when to use which tool, and can route to the right technology agent.
When a request targets a specific technology, delegate to the appropriate agent:
| Signal | Technology Agent | Scope |
|--------|-----------------|-------|
| PowerShell, pwsh, cmdlet, pipeline, .ps1 | powershell/SKILL.md | PowerShell 7.4/7.6 LTS, cross-platform scripting |
| Bash, shell, sh, .sh, sed, awk, grep, jq | bash/SKILL.md | Bash 5.x, POSIX shell, Unix text processing |
| Python script, pip, venv, pathlib, argparse | python/SKILL.md | Python 3.10-3.14 for scripting/automation |
| Node.js script, npm script | (future) | Node.js CLI tools |
| Azure CLI, az command | (future) | Azure resource management |
| AWS CLI, aws command | (future) | AWS resource management |
| kubectl, Kubernetes CLI | (future) | Kubernetes cluster management |
If the technology is ambiguous, use the Language Selection Guide below.
Identify the language -- Look for file extensions, shebang lines, syntax patterns, or explicit mentions. If unclear, ask or recommend based on the task.
Route to technology agent -- Load the appropriate SKILL.md for deep expertise.
Apply cross-language principles -- The concepts below apply regardless of language.
Recommend -- Provide actionable, tested guidance.
Choose the right tool for the job:
-WhatIf, -Confirm, -Verbose support| Factor | Bash | PowerShell | Python | |--------|------|------------|--------| | Text stream processing | Best | Good | Good | | Structured data / objects | Poor | Best | Good | | Windows administration | Poor | Best | Fair | | Linux administration | Best | Good | Good | | API interaction | Fair | Good | Best | | Complex logic (>100 LOC) | Poor | Good | Best | | Third-party ecosystem | Fair | Good | Best | | Startup time | Fastest | Slow | Fast | | Learning curve | Medium | Medium | Low |
Every process returns an integer exit code. Zero means success; non-zero means failure.
# Bash: $? holds last exit code
command
echo $? # 0 = success
# PowerShell: $LASTEXITCODE for native commands, $? for cmdlets
git status
$LASTEXITCODE # 0 = success
Get-Item missing.txt
$? # $false = cmdlet failed
# Python: subprocess.run returns CompletedProcess with .returncode
import subprocess
result = subprocess.run(["git", "status"], capture_output=True)
result.returncode # 0 = success
All three languages work with three standard streams: stdin (fd 0), stdout (fd 1), stderr (fd 2).
# Bash: redirect with >, 2>, &>, |
command > out.txt 2> err.txt # separate stdout/stderr
command 2>&1 | tee log.txt # combine and tee
command < input.txt # pipe file to stdin
# PowerShell: streams are numbered (1=output, 2=error, 3=warning, etc.)
command > out.txt 2> err.txt
command *> all.txt # all streams
Write-Error "problem" 2> Variable:errs
# Python: subprocess handles streams explicitly
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(result.stdout)
print(result.stderr)
# Bash: export for child processes
export API_KEY="secret"
echo "$API_KEY"
API_KEY=val command # set for single command only
# PowerShell: $env: drive
$env:API_KEY = 'secret'
[System.Environment]::GetEnvironmentVariable('PATH', 'Machine')
# Python: os.environ dict
import os
key = os.environ.get("API_KEY", "default")
os.environ["NEW_VAR"] = "value" # for child processes
# Bash: getopts (short) or manual while/case (long options)
while [[ $# -gt 0 ]]; do
case $1 in
-v|--verbose) VERBOSE=true; shift ;;
-o|--output) OUTPUT="$2"; shift 2 ;;
*) ARGS+=("$1"); shift ;;
esac
done
# PowerShell: param() block with attributes
param(
[Parameter(Mandatory)][string]$Path,
[ValidateSet('csv','json')][string]$Format = 'csv',
[switch]$Verbose
)
# Python: argparse module
import argparse
parser = argparse.ArgumentParser(description="My tool")
parser.add_argument("path", help="Input file")
parser.add_argument("-f", "--format", choices=["csv","json"], default="csv")
parser.add_argument("-v", "--verbose", action="store_true")
args = parser.parse_args()
# Bash: set -euo pipefail + trap
set -euo pipefail
trap 'echo "Error at line $LINENO"; exit 1' ERR
# PowerShell: try/catch + $ErrorActionPreference
$ErrorActionPreference = 'Stop'
try { risky_operation } catch { Write-Error $_.Exception.Message }
# Python: try/except with specific exceptions
try:
risky_operation()
except FileNotFoundError as e:
logging.error("File missing: %s", e)
sys.exit(1)
Pipes connect commands. Each language handles them differently:
cmd1 | cmd2 | cmd3Get-Process | Where-Object CPU -gt 50 | Select-Object Name, CPU# Bash: trap for signals
trap 'cleanup; exit' INT TERM HUP
trap cleanup EXIT
# PowerShell: Register-EngineEvent or try/finally
try { long_operation } finally { cleanup }
# Python: signal module
import signal
signal.signal(signal.SIGTERM, lambda sig, frame: cleanup())
1. Forgetting to quote variables in Bash
Unquoted variables undergo word splitting and glob expansion. Always use "$var", never bare $var.
2. Ignoring exit codes
Always check $? (Bash), $LASTEXITCODE (PowerShell), or .returncode (Python subprocess). Unchecked failures cascade silently.
3. Using shell=True in Python subprocess
subprocess.run(cmd, shell=True) is a command injection risk. Pass a list of arguments instead: subprocess.run(["git", "status"]).
4. Hardcoding paths with wrong separators
Use os.path.join() or pathlib.Path in Python, Join-Path in PowerShell, and "$dir/$file" in Bash. Never hardcode \ or /.
5. Not handling encoding
Specify encoding="utf-8" explicitly in Python file operations. In PowerShell, use -Encoding UTF8. In Bash, ensure LANG or LC_ALL is set.
6. Running destructive operations without dry-run mode
Always implement --dry-run / -WhatIf for scripts that modify, delete, or move files.
For deep expertise in a specific technology, delegate to:
powershell/SKILL.md -- PowerShell 7.4/7.6 LTS: pipelines, modules, remoting, parallel executionbash/SKILL.md -- Bash 5.x: variables, text processing (grep/sed/awk/jq), process management, networkingpython/SKILL.md -- Python 3.10-3.14: file ops, subprocess, HTTP/API, argparse, system automationtools
kubectl command-line usage and scripting: kubeconfig and context management, output formats (jsonpath, custom-columns, go-template), all major verbs (get, describe, apply, delete, exec, logs, port-forward, rollout, scale, drain), workload resources, config/storage, networking, RBAC, node management, debugging (CrashLoopBackOff, ImagePullBackOff, OOMKilled), and scripting patterns (dry-run, diff, wait, jq, kustomize). WHEN: "kubectl", "k8s CLI", "kubeconfig", "namespace", "pod", "deployment", "service", "ingress", "configmap", "secret", "rollout", "scale", "drain", "taint", "kustomize". Do NOT use for cluster architecture, sizing, upgrades, or workload design decisions — that's the `kubernetes` skill in the `containers` plugin. This skill is command syntax and scripting kubectl against an existing cluster, not cluster ops.
tools
Bash 5.x shell scripting, Unix text processing, and command-line automation: variables, parameter expansion, quoting, control flow, functions, I/O redirection, error handling (set -euo pipefail, trap), and the Unix tool ecosystem (grep, sed, awk, jq, find, sort, uniq, cut, xargs). Covers process management, networking (curl, ssh, rsync, nc), file locking (flock), parallel execution, and production script patterns. WHEN: "Bash", "bash", "shell", "sh", ".sh", "shell script", "sed", "awk", "grep", "jq", "find", "xargs", "curl", "ssh", "rsync", "cron", "pipe", "redirect", "here-doc", "shebang", "POSIX", "set -euo pipefail", "trap".
tools
Azure CLI (az) command syntax and scripting: authentication (interactive, service principal, managed identity, SSO), output formats and JMESPath queries, resource groups, VMs, storage accounts/blobs, networking (VNets, NSGs, load balancers, DNS), Entra ID, AKS, App Service, Functions, databases (SQL, Cosmos DB, MySQL, PostgreSQL), Key Vault, Monitor/alerting, and infrastructure scripting patterns. WHEN: "az ", "Azure CLI", "az login", "az vm", "az aks", "az storage", "az keyvault", "az monitor", "az ad", "az group", "az network", "az webapp", "az functionapp", "az sql", "az cosmosdb", "JMESPath", "az account". Do NOT use for Azure architecture, landing zones, or multi-subscription strategy — that's the `cloud-platforms` plugin. This skill is about command syntax and scripting the CLI, not deciding what to provision.
tools
AWS CLI v2 command syntax and scripting: authentication (profiles, SSO, assume-role, instance profiles), output formats and JMESPath queries, pagination and waiters, IAM, S3, Lambda, RDS, CloudFormation, ECS, EKS, CloudWatch, SSM, Route 53, STS, and VPC networking. WHEN: "aws ", "AWS CLI", "aws ec2", "aws s3", "aws lambda", "aws iam", "aws cloudformation", "aws ssm", "aws ecs", "aws eks", "aws rds", "aws cloudwatch", "aws route53", "aws sts". Do NOT use for AWS architecture, service selection, multi-account strategy, or FinOps — that's the `cloud-platforms` plugin. This skill is about command syntax and scripting the CLI, not deciding what to provision.