← Back to list

shell-scripting
by mylee04
Cross-platform desktop notifications for Claude Code/Codex/Gemini - Get alerts when tasks complete
⭐ 57🍴 4📅 Jan 22, 2026
SKILL.md
name: shell-scripting description: Shell scripting best practices for cross-platform CLI tools
Shell Scripting Standards
When to Use
- Writing new shell scripts
- Refactoring existing scripts
- Adding new functions
Script Structure
1. File Header
#!/bin/bash
# Script description
# https://github.com/mylee04/code-notify
set -e # Exit on error
2. Constants (UPPER_CASE)
VERSION="1.2.0"
CONFIG_DIR="$HOME/.claude"
DEFAULT_SOUND="Glass"
3. Functions (snake_case)
# Description of function
# Arguments: $1 = name, $2 = optional value
function_name() {
local name="$1"
local value="${2:-default}"
# Function body
}
4. Main Logic
# Main execution
main() {
validate_args "$@"
do_work
cleanup
}
main "$@"
Best Practices
Variable Handling
# Good - quoted variables
echo "$message"
path="$HOME/.config"
# Bad - unquoted
echo $message
path=$HOME/.config
Conditionals
# Good - double brackets
if [[ -n "$var" ]]; then
echo "not empty"
fi
# Bad - single brackets
if [ -n "$var" ]; then
echo "not empty"
fi
Command Existence Check
# Good
if command -v terminal-notifier &> /dev/null; then
terminal-notifier -message "Hello"
fi
# Bad
if which terminal-notifier; then
terminal-notifier -message "Hello"
fi
Error Handling
# Good - explicit error handling
if ! some_command; then
echo "Error: command failed" >&2
exit 1
fi
# Good - trap for cleanup
cleanup() {
rm -f "$temp_file"
}
trap cleanup EXIT
Local Variables in Functions
# Good
my_function() {
local input="$1"
local result
result=$(process "$input")
echo "$result"
}
# Bad - pollutes global scope
my_function() {
input="$1"
result=$(process "$input")
echo "$result"
}
Common Patterns
OS Detection
detect_os() {
case "$(uname -s)" in
Darwin*) echo "macos" ;;
Linux*) echo "linux" ;;
CYGWIN*|MINGW*|MSYS*) echo "windows" ;;
*) echo "unknown" ;;
esac
}
Safe File Operations
# Create directory if not exists
mkdir -p "$dir"
# Safe file reading
if [[ -f "$config_file" ]]; then
config=$(cat "$config_file")
fi
# Atomic write
echo "$content" > "$file.tmp" && mv "$file.tmp" "$file"
JSON Handling (without jq)
# Simple grep-based check
if grep -q '"enabled":\s*true' "$file"; then
echo "enabled"
fi
# With jq (if available)
if command -v jq &> /dev/null; then
value=$(jq -r '.key' "$file")
fi
Testing
Test Function Output
test_detect_os() {
result=$(detect_os)
if [[ "$result" != "macos" ]] && [[ "$result" != "linux" ]]; then
echo "FAIL: unexpected OS: $result"
return 1
fi
echo "PASS"
}
Test Exit Codes
test_error_handling() {
if invalid_command 2>/dev/null; then
echo "FAIL: should have failed"
return 1
fi
echo "PASS"
}
Success Metrics
- shellcheck passes with no warnings
- All functions use local variables
- All variables are quoted
- Commands existence checked before use
- Error handling for all failure points
Score
Total Score
65/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon


