Skip to main content

shell

Shell scripting standards for Scenescape — shebang, style, and Bash guidelines.

소스 정보

저장소
open-edge-platform/scenescape
최근 소스 활동
2026년 6월 18일 10:00
감지된 SKILL.md 언어
영어
스타
47
포크
51

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
shell
description
Shell scripting standards for Scenescape — shebang, style, and Bash guidelines.
# Shell Scripting Standards for Scenescape ## Shebang Use `#!/usr/bin/env bash` for portability: ```bash #!/usr/bin/env bash ``` Not `#!/bin/bash` (less portable) or `#!/bin/sh` (POSIX only, limiting). ## Code Style ### Linting - **Linter**: shellcheck with style warnings - **Command**: ```bash make lint-shell # Lint all .sh files ``` ### Indentation - Use **2 spaces** (never tabs) - Consistent with project standards ### Line Length - Target: 80-100 characters for readability - Break long commands with `\` line continuation ```bash if [[ condition ]]; then echo "Indented with 2 spaces" if [[ nested ]]; then echo "Nested indentation" fi fi ``` ## Best Practices ### Exit on Error Use `set -e` to exit on any error: ```bash #!/usr/bin/env bash set -e # Exit immediately if a command fails set -o pipefail # Fail if any command in pipeline fails # Now any failing command will exit the script command1 command2 command3 ``` ### Strict Mode For critical scripts, use strict mode: ```bash set -euo pipefail # -e: exit on error # -u: exit on undefined variable # -o pipefail: fail on pipe errors ``` ### Trap Errors Clean up on exit or error: ```bash cleanup() { echo "Cleaning up..." rm -f /tmp/tempfile } trap cleanup EXIT trap 'echo "Error on line $LINENO"' ERR ``` ## Variables ### Naming - **Local variables**: `lowercase_with_underscores` - **Environment/Global**: `UPPERCASE_WITH_UNDERSCORES` - **Read-only**: `readonly CONSTANT_VALUE` ```bash # Local local temp_file="/tmp/data" local count=0 # Global/Environment WORKSPACE_DIR="/workspace" export DATABASE_PASSWORD # Constants readonly MAX_RETRIES=3 ``` ### Quoting Always quote variables to prevent word splitting: ```bash # Good file_path="/path/with spaces/file.txt" cat "$file_path" # Bad - breaks with spaces cat $file_path ``` ### Default Values ```bash # Use default if variable is unset config_file="${CONFIG_FILE:-/etc/default.conf}" # Use default if variable is unset or empty database="${DATABASE_NAME:=scenescape}" # Error if variable is unset required="${REQUIRED_VAR:?Error: REQUIRED_VAR must be set}" ``` ## Conditionals ### Use `[[ ]]` for Tests Prefer `[[ ]]` over `[ ]` or `test`: ```bash # Good - modern test if [[ -f "$file" ]]; then echo "File exists" fi if [[ "$value" == "expected" ]]; then echo "Match" fi # Pattern matching if [[ "$filename" == *.txt ]]; then echo "Text file" fi ``` ### Common Test Operators ```bash # File tests [[ -f "$file" ]] # File exists [[ -d "$dir" ]] # Directory exists [[ -r "$file" ]] # Readable [[ -w "$file" ]] # Writable [[ -x "$file" ]] # Executable # String tests [[ -z "$string" ]] # Empty string [[ -n "$string" ]] # Non-empty string [[ "$a" == "$b" ]] # Equal [[ "$a" != "$b" ]] # Not equal # Numeric tests [[ "$a" -eq "$b" ]] # Equal [[ "$a" -ne "$b" ]] # Not equal [[ "$a" -lt "$b" ]] # Less than [[ "$a" -gt "$b" ]] # Greater than ``` ### Short-Circuit Logic ```bash # Execute command2 only if command1 succeeds command1 && command2 # Execute command2 only if command1 fails command1 || command2 # Multiple conditions [[ -f "$file" ]] && [[ -r "$file" ]] && cat "$file" ``` ## Functions ### Declaration ```bash function_name() { local arg1="$1" local arg2="$2" # Function body echo "Processing: $arg1, $arg2" return 0 } # Call function function_name "value1" "value2" ``` ### Return Values ```bash check_status() { if [[ condition ]]; then return 0 # Success else return 1 # Failure fi } # Use return value if check_status; then echo "Check passed" else echo "Check failed" fi ``` ### Local Variables Always use `local` for function variables: ```bash process_data() { local input="$1" local temp_file="/tmp/temp_$$" # Process data # ... } ``` ## Command Substitution Use `$()` instead of backticks: ```bash # Good current_date=$(date +%Y-%m-%d) file_count=$(ls | wc -l) # Avoid (backticks) current_date=`date +%Y-%m-%d` ``` ## Loops ### For Loops ```bash # Iterate over list for item in item1 item2 item3; do echo "$item" done # Iterate over files for file in /path/*.txt; do [[ -f "$file" ]] && process "$file" done # C-style loop for ((i = 0; i < 10; i++)); do echo "Iteration $i" done ``` ### While Loops ```bash # Read file line by line while IFS= read -r line; do echo "Line: $line" done < input.txt # Condition-based count=0 while [[ $count -lt 10 ]]; do echo "$count" ((count++)) done ``` ## Arrays ### Declaration and Access ```bash # Declare array declare -a services=("controller" "manager" "autocalibration") # Access elements echo "${services[0]}" # First element echo "${services[@]}" # All elements echo "${#services[@]}" # Array length # Iterate for service in "${services[@]}"; do echo "Service: $service" done ``` ### Adding Elements ```bash services+=("mapping") ``` ## Error Handling ### Check Command Success ```bash if command_that_might_fail; then echo "Success" else echo "Failed with exit code: $?" exit 1 fi ``` ### Error Messages to stderr ```bash error_exit() { echo "Error: $1" >&2 exit 1 } # Usage [[ -f "$config_file" ]] || error_exit "Config file not found: $config_file" ``` ### Verbose Error Output ```bash set -x # Enable debug output (prints each command) # Commands here will be echoed set +x # Disable debug output ``` ## File Operations ### Reading Files ```bash # Read entire file content=$(cat file.txt) # Read line by line while IFS= read -r line; do echo "$line" done < file.txt ``` ### Writing Files ```bash # Overwrite echo "content" > file.txt # Append echo "more content" >> file.txt # Here document cat > config.txt << EOF setting1=value1 setting2=value2 EOF ``` ### Temporary Files ```bash temp_file=$(mktemp) trap "rm -f '$temp_file'" EXIT # Use temp file echo "data" > "$temp_file" ``` ## Path Handling ### Absolute Paths ```bash # Get script directory script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # Construct absolute paths config_file="$script_dir/config.txt" ``` ### Path Components ```bash filepath="/path/to/file.txt" dirname=$(dirname "$filepath") # /path/to basename=$(basename "$filepath") # file.txt filename="${basename%.*}" # file extension="${basename##*.}" # txt ``` ## Process Management ### Background Jobs ```bash # Start background job long_running_command & pid=$! # Wait for specific job wait $pid # Wait for all background jobs wait ``` ### Process Substitution ```bash # Compare outputs of two commands diff <(command1) <(command2) # Read from command output while read -r line; do echo "$line" done < <(command) ``` ## Scenescape-Specific Patterns ### Docker Commands ```bash # Build with progress env BUILDKIT_PROGRESS=plain docker build \ --build-arg VERSION="$VERSION" \ -t "scenescape-service:$VERSION" \ . ``` ### Environment Variables ```bash # Check required variables : "${SUPASS:?SUPASS environment variable must be set}" : "${DATABASE_PASSWORD:?DATABASE_PASSWORD must be set}" ``` ### Makefile Integration ```bash # Get variables from Makefile VERSION=$(cat version.txt) BUILD_DIR="${BUILD_DIR:-build}" ``` ## Common Patterns ### Retry Logic ```bash retry_command() { local max_attempts=3 local attempt=1 while [[ $attempt -le $max_attempts ]]; do if command_to_retry; then return 0 fi echo "Attempt $attempt failed, retrying..." >&2 ((attempt++)) sleep 2 done return 1 } ``` ### Input Validation ```bash validate_input() { local input="$1" if [[ -z "$input" ]]; then echo "Error: Input cannot be empty" >&2 return 1 fi if [[ ! "$input" =~ ^[0-9]+$ ]]; then echo "Error: Input must be numeric" >&2 return 1 fi return 0 } ``` ### Logging ```bash log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" } log_error() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $*" >&2 } log "Starting process" log_error "Something went wrong" ``` ## Anti-Patterns to Avoid ❌ **Don't use `eval`** (security risk): ```bash # Bad eval "$user_input"
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기