新增SHELL得SKILL
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: developing-project-management
|
||||
description: Guides development of rmdc-project-management module including project lifecycle management, version control (Git-like), ACL permissions, TOTP authorization, and workflow integration. Triggered when modifying project CRUD, draft/version APIs, permission grants, or authorization features. Keywords: project lifecycle, version snapshot, ACL, TOTP, workflow callback, SuperAdmin.
|
||||
description: Guides development of rmdc-project-management module including project lifecycle management, version control (Git-like), ACL permissions, TOTP authorization, and workflow integration. Triggered when modifying project CRUD, draft/version APIs, permission grants, or authorization features. Keywords: project mangement, project lifecycle, version snapshot, ACL, TOTP, workflow callback, SuperAdmin.
|
||||
argument-hint: "<change-type> [target]" where change-type is one of: api|entity|service|migration|frontend|auth. Example: "api draft-submit" or "migration add-field"
|
||||
allowed-tools:
|
||||
- Read
|
||||
|
||||
204
1-AgentSkills/writing-bash-scripts/SKILL.md
Normal file
204
1-AgentSkills/writing-bash-scripts/SKILL.md
Normal file
@@ -0,0 +1,204 @@
|
||||
---
|
||||
name: writing-bash-scripts
|
||||
description: Generates production-grade Bash scripts with strict mode, modular structure, unified logging, error handling, and ShellCheck compliance. Triggered by requests like "write a bash script", "create shell script", "generate CLI tool in bash". Keywords: bash, shell, script, devops.
|
||||
argument-hint: "<functional-requirement-description>"
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Write
|
||||
- Bash
|
||||
- Glob
|
||||
- Grep
|
||||
---
|
||||
|
||||
# Writing Production-Grade Bash Scripts
|
||||
|
||||
## Purpose
|
||||
Transform functional requirements into a single, deployable Bash script following engineering best practices.
|
||||
|
||||
## Arguments
|
||||
`$ARGUMENTS` = functional requirement description (目标、输入/输出、流程、约束、示例数据等)
|
||||
|
||||
If `$ARGUMENTS` is empty, prompt user for:
|
||||
- Target functionality
|
||||
- Input/output specification
|
||||
- Constraints (OS, permissions, dependencies)
|
||||
|
||||
## Dynamic Context
|
||||
|
||||
!`echo "Current working directory: $(pwd)"`
|
||||
|
||||
!`bash --version | head -1`
|
||||
|
||||
---
|
||||
|
||||
## Plan Phase
|
||||
|
||||
### Deliverables Checklist
|
||||
- [ ] Single `.sh` file with shebang `#!/usr/bin/env bash`
|
||||
- [ ] Bash >= 5.0 requirement documented
|
||||
- [ ] ASCII call graph at script top
|
||||
- [ ] usage/help function (-h/--help)
|
||||
- [ ] Parameter parsing (getopts)
|
||||
- [ ] Exit code documentation
|
||||
- [ ] --dry-run support
|
||||
- [ ] --verbose/--quiet support
|
||||
- [ ] Cleanup trap for temp files
|
||||
|
||||
### Decision Points
|
||||
| Decision | Default | Override Condition |
|
||||
|----------|---------|-------------------|
|
||||
| POSIX vs Bash-specific | POSIX preferred | Use Bash features only when necessary (arrays, `[[ ]]`, mapfile); comment reason |
|
||||
| Destructive ops | Require `--force` | Never auto-delete without confirmation |
|
||||
| Temp file location | `mktemp -d` | User-specified via `--tmp-dir` |
|
||||
|
||||
---
|
||||
|
||||
## Execute Phase
|
||||
|
||||
### Script Structure (固定顺序)
|
||||
|
||||
```
|
||||
1. Shebang + Metadata
|
||||
2. ASCII Call Graph
|
||||
3. Global Constants (readonly)
|
||||
4. Strict Mode Setup
|
||||
5. Dependency/Environment Checks
|
||||
6. Logging & Error Handling Functions
|
||||
7. Business Functions
|
||||
8. main() + Entry Point
|
||||
9. Self-test Examples (comments)
|
||||
```
|
||||
|
||||
### Strict Mode (必须)
|
||||
```bash
|
||||
set -Eeuo pipefail
|
||||
IFS=$' \t\n'
|
||||
```
|
||||
|
||||
### Required Functions
|
||||
|
||||
| Function | Purpose |
|
||||
|----------|---------|
|
||||
| `usage` | Print help with examples |
|
||||
| `die` | `die <msg> <exit_code>` - unified error exit |
|
||||
| `log_debug/info/warn/error` | Timestamped logging with LOG_LEVEL control |
|
||||
| `run_cmd` | Command wrapper: dry-run, retry, error capture |
|
||||
| `cleanup` | Remove temp files/locks on EXIT/ERR/INT/TERM |
|
||||
|
||||
### Function Documentation Format
|
||||
```bash
|
||||
### <one-line description>
|
||||
### @param <name> <type> <purpose>
|
||||
### @return <exit_code> <status>
|
||||
### @require <dependency/permission>
|
||||
### @side_effect <file/network/system impact>
|
||||
function_name() {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Exit Codes
|
||||
| Code | Meaning |
|
||||
|------|---------|
|
||||
| 0 | Success |
|
||||
| 1 | General error |
|
||||
| 2 | Invalid arguments |
|
||||
| 3 | Missing dependency |
|
||||
| 4 | Permission denied |
|
||||
| 5 | File/resource not found |
|
||||
| 126 | Command not executable |
|
||||
| 127 | Command not found |
|
||||
|
||||
> See `reference/exit-codes.md` for extended codes.
|
||||
|
||||
### Logging Format
|
||||
```
|
||||
[YYYY-MM-DD HH:MM:SS] [LEVEL] message
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verify Phase
|
||||
|
||||
### Pre-Delivery Checklist
|
||||
|
||||
#### Frontmatter & Structure
|
||||
- [ ] Shebang is `#!/usr/bin/env bash`
|
||||
- [ ] Bash version requirement stated
|
||||
- [ ] ASCII call graph present
|
||||
- [ ] Sections in correct order
|
||||
|
||||
#### Safety & Defaults
|
||||
- [ ] `set -Eeuo pipefail` enabled
|
||||
- [ ] All variables double-quoted (except intentional word splitting with comment)
|
||||
- [ ] No unquoted `$@` or `$*`
|
||||
- [ ] No unsafe `eval`
|
||||
- [ ] `--dry-run` implemented
|
||||
- [ ] `--force` required for destructive ops
|
||||
- [ ] `mktemp` used for temp files
|
||||
- [ ] trap covers EXIT/ERR/INT/TERM
|
||||
|
||||
#### Functions
|
||||
- [ ] Every function has `###` doc block
|
||||
- [ ] `@param`, `@return`, `@require` present
|
||||
- [ ] snake_case naming
|
||||
- [ ] Input validation on all external inputs
|
||||
|
||||
#### Logging & Errors
|
||||
- [ ] `log_*` functions implemented
|
||||
- [ ] LOG_LEVEL controls output
|
||||
- [ ] `die` includes line number and function stack
|
||||
- [ ] `run_cmd` wrapper used for external commands
|
||||
|
||||
#### Quality
|
||||
- [ ] Passes ShellCheck (or disables with `# shellcheck disable=SCxxxx` + reason)
|
||||
- [ ] 3+ self-test examples in comments (normal, error, dry-run)
|
||||
- [ ] No hardcoded paths without override option
|
||||
|
||||
### ShellCheck Validation
|
||||
```bash
|
||||
shellcheck -x -s bash <script.sh>
|
||||
```
|
||||
|
||||
> Use `scripts/shellcheck-wrapper.sh` for automated checking.
|
||||
|
||||
---
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
| Pitfall | Fix |
|
||||
|---------|-----|
|
||||
| Unquoted variables in paths with spaces | Always `"$var"` |
|
||||
| Missing `local` in functions | Declare with `local var=...` |
|
||||
| Assuming GNU tools on macOS | Check `uname` or use portable flags |
|
||||
| Ignoring exit code of piped commands | `set -o pipefail` + check `${PIPESTATUS[@]}` |
|
||||
| Temp files left on error | Trap cleanup on ERR/EXIT |
|
||||
|
||||
---
|
||||
|
||||
## Reference Files
|
||||
|
||||
| When | Read |
|
||||
|------|------|
|
||||
| Need detailed code structure | `reference/code-structure.md` |
|
||||
| Writing function docs | `reference/function-template.md` |
|
||||
| Defining custom exit codes | `reference/exit-codes.md` |
|
||||
| Starting from scratch | `examples/minimal-template.sh` |
|
||||
|
||||
---
|
||||
|
||||
## Minimal Self-Test Commands
|
||||
|
||||
```bash
|
||||
# 1. Help
|
||||
./script.sh --help
|
||||
|
||||
# 2. Dry-run
|
||||
./script.sh --dry-run <args>
|
||||
|
||||
# 3. Invalid argument (expect exit 2)
|
||||
./script.sh --invalid-option
|
||||
|
||||
# 4. Verbose mode
|
||||
./script.sh --verbose <args>
|
||||
```
|
||||
362
1-AgentSkills/writing-bash-scripts/examples/minimal-template.sh
Normal file
362
1-AgentSkills/writing-bash-scripts/examples/minimal-template.sh
Normal file
@@ -0,0 +1,362 @@
|
||||
#!/usr/bin/env bash
|
||||
#===============================================================================
|
||||
# Script Name : minimal-template.sh
|
||||
# Description : Minimal production-grade Bash script template
|
||||
# Author : <author>
|
||||
# Version : 1.0.0
|
||||
# License : MIT
|
||||
# Last Updated : <date>
|
||||
# Bash Version : >= 5.0
|
||||
#
|
||||
# Assumptions:
|
||||
# - Running on Linux/macOS with GNU coreutils
|
||||
# - UTF-8 locale available
|
||||
#===============================================================================
|
||||
|
||||
#===============================================================================
|
||||
# ASCII CALL GRAPH
|
||||
#===============================================================================
|
||||
# main()
|
||||
# ├── parse_args()
|
||||
# ├── check_dependencies()
|
||||
# ├── setup_temp()
|
||||
# ├── do_work()
|
||||
# │ └── helper_function()
|
||||
# └── cleanup() [via trap]
|
||||
#===============================================================================
|
||||
|
||||
#===============================================================================
|
||||
# GLOBAL CONSTANTS
|
||||
#===============================================================================
|
||||
readonly VERSION="1.0.0"
|
||||
readonly SCRIPT_NAME="${0##*/}"
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Exit codes
|
||||
readonly E_SUCCESS=0
|
||||
readonly E_GENERAL=1
|
||||
readonly E_ARGS=2
|
||||
readonly E_DEPS=3
|
||||
readonly E_PERM=4
|
||||
readonly E_NOTFOUND=5
|
||||
|
||||
#===============================================================================
|
||||
# STRICT MODE
|
||||
#===============================================================================
|
||||
set -Eeuo pipefail
|
||||
IFS=$' \t\n'
|
||||
|
||||
#===============================================================================
|
||||
# CONFIGURABLE DEFAULTS
|
||||
#===============================================================================
|
||||
LOG_LEVEL="${LOG_LEVEL:-INFO}"
|
||||
DRY_RUN=false
|
||||
VERBOSE=false
|
||||
FORCE=false
|
||||
TEMP_DIR=""
|
||||
|
||||
#===============================================================================
|
||||
# LOGGING & ERROR HANDLING
|
||||
#===============================================================================
|
||||
|
||||
### Log message at DEBUG level
|
||||
### @param message string Message to log
|
||||
### @return 0 Always
|
||||
log_debug() {
|
||||
[[ "${LOG_LEVEL}" == "DEBUG" ]] || return 0
|
||||
printf '[%s] [DEBUG] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2
|
||||
}
|
||||
|
||||
### Log message at INFO level
|
||||
### @param message string Message to log
|
||||
### @return 0 Always
|
||||
log_info() {
|
||||
[[ "${LOG_LEVEL}" =~ ^(DEBUG|INFO)$ ]] || return 0
|
||||
printf '[%s] [INFO] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2
|
||||
}
|
||||
|
||||
### Log message at WARN level
|
||||
### @param message string Message to log
|
||||
### @return 0 Always
|
||||
log_warn() {
|
||||
[[ "${LOG_LEVEL}" =~ ^(DEBUG|INFO|WARN)$ ]] || return 0
|
||||
printf '[%s] [WARN] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2
|
||||
}
|
||||
|
||||
### Log message at ERROR level
|
||||
### @param message string Message to log
|
||||
### @return 0 Always
|
||||
log_error() {
|
||||
printf '[%s] [ERROR] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2
|
||||
}
|
||||
|
||||
### Exit with error message, location info, and exit code
|
||||
### @param message string Error message
|
||||
### @param exit_code int Exit code (default: 1)
|
||||
### @return never Exits script
|
||||
### @side_effect Terminates script
|
||||
die() {
|
||||
local message="$1"
|
||||
local exit_code="${2:-$E_GENERAL}"
|
||||
local caller_info=""
|
||||
|
||||
# > Build caller info for debugging
|
||||
if [[ "${BASH_LINENO[0]:-0}" -gt 0 ]]; then
|
||||
caller_info=" (${FUNCNAME[1]:-main}:${BASH_LINENO[0]:-?})"
|
||||
fi
|
||||
|
||||
log_error "${message}${caller_info}"
|
||||
exit "$exit_code"
|
||||
}
|
||||
|
||||
### Execute command with dry-run support
|
||||
### @param cmd array Command and arguments
|
||||
### @return 0 Success
|
||||
### @return 1 Command failed
|
||||
### @side_effect Executes external command
|
||||
run_cmd() {
|
||||
local -a cmd=("$@")
|
||||
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
log_info "[DRY-RUN] Would execute: ${cmd[*]}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
[[ "${VERBOSE}" == "true" ]] && log_debug "Executing: ${cmd[*]}"
|
||||
|
||||
if ! "${cmd[@]}"; then
|
||||
log_error "Command failed: ${cmd[*]}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
### Cleanup temporary resources
|
||||
### @return 0 Always
|
||||
### @side_effect Removes temp directory
|
||||
cleanup() {
|
||||
local exit_code=$?
|
||||
|
||||
if [[ -n "${TEMP_DIR:-}" && -d "${TEMP_DIR}" ]]; then
|
||||
rm -rf "${TEMP_DIR}"
|
||||
log_debug "Cleaned up temp dir: ${TEMP_DIR}"
|
||||
fi
|
||||
|
||||
exit "$exit_code"
|
||||
}
|
||||
|
||||
# > Set traps for cleanup on exit/error/interrupt
|
||||
trap cleanup EXIT ERR INT TERM
|
||||
|
||||
#===============================================================================
|
||||
# DEPENDENCY & ENVIRONMENT CHECKS
|
||||
#===============================================================================
|
||||
|
||||
### Check Bash version meets minimum requirement
|
||||
### @return 0 Version OK
|
||||
### @return 1 Version too old
|
||||
### @require Bash >= 5.0
|
||||
check_bash_version() {
|
||||
local required_major=5
|
||||
local required_minor=0
|
||||
local current_major="${BASH_VERSINFO[0]}"
|
||||
local current_minor="${BASH_VERSINFO[1]}"
|
||||
|
||||
if (( current_major < required_major )) || \
|
||||
(( current_major == required_major && current_minor < required_minor )); then
|
||||
die "Bash >= ${required_major}.${required_minor} required (current: ${current_major}.${current_minor})" "$E_DEPS"
|
||||
fi
|
||||
}
|
||||
|
||||
### Check required external commands exist
|
||||
### @return 0 All dependencies present
|
||||
### @return 3 Missing dependency
|
||||
check_dependencies() {
|
||||
local -a required_cmds=("date" "mktemp" "rm") # > Add your dependencies here
|
||||
local cmd
|
||||
|
||||
for cmd in "${required_cmds[@]}"; do
|
||||
if ! command -v "$cmd" &>/dev/null; then
|
||||
die "Required command not found: $cmd" "$E_DEPS"
|
||||
fi
|
||||
done
|
||||
|
||||
log_debug "All dependencies satisfied"
|
||||
}
|
||||
|
||||
#===============================================================================
|
||||
# HELPER FUNCTIONS
|
||||
#===============================================================================
|
||||
|
||||
### Create temporary directory
|
||||
### @return 0 Success
|
||||
### @side_effect Sets TEMP_DIR global
|
||||
setup_temp() {
|
||||
TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/${SCRIPT_NAME}.XXXXXX")"
|
||||
readonly TEMP_DIR
|
||||
log_debug "Created temp dir: ${TEMP_DIR}"
|
||||
}
|
||||
|
||||
### Display usage information
|
||||
### @return 0 Always
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ${SCRIPT_NAME} [OPTIONS] <argument>
|
||||
|
||||
Description:
|
||||
Brief description of what this script does.
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message
|
||||
-v, --verbose Enable verbose output
|
||||
-q, --quiet Suppress non-error output
|
||||
-n, --dry-run Show what would be done without executing
|
||||
-f, --force Force operation (skip confirmations)
|
||||
--version Show version information
|
||||
|
||||
Arguments:
|
||||
<argument> Description of required argument
|
||||
|
||||
Examples:
|
||||
${SCRIPT_NAME} --help
|
||||
${SCRIPT_NAME} --dry-run input.txt
|
||||
${SCRIPT_NAME} --verbose --force input.txt
|
||||
|
||||
Exit Codes:
|
||||
0 Success
|
||||
1 General error
|
||||
2 Invalid arguments
|
||||
3 Missing dependency
|
||||
4 Permission denied
|
||||
5 Resource not found
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
#===============================================================================
|
||||
# BUSINESS FUNCTIONS
|
||||
#===============================================================================
|
||||
|
||||
### Main business logic (replace with actual implementation)
|
||||
### @param input string Input to process
|
||||
### @return 0 Success
|
||||
### @return 1 Processing failed
|
||||
do_work() {
|
||||
local input="$1"
|
||||
|
||||
log_info "Processing: ${input}"
|
||||
|
||||
# > Replace with actual business logic
|
||||
run_cmd echo "Working on: ${input}"
|
||||
|
||||
log_info "Done"
|
||||
}
|
||||
|
||||
#===============================================================================
|
||||
# ARGUMENT PARSING
|
||||
#===============================================================================
|
||||
|
||||
### Parse command line arguments
|
||||
### @param args array Command line arguments
|
||||
### @return 0 Success
|
||||
### @return 2 Invalid argument
|
||||
parse_args() {
|
||||
local positional=()
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
usage
|
||||
exit "$E_SUCCESS"
|
||||
;;
|
||||
--version)
|
||||
echo "${SCRIPT_NAME} version ${VERSION}"
|
||||
exit "$E_SUCCESS"
|
||||
;;
|
||||
-v|--verbose)
|
||||
VERBOSE=true
|
||||
LOG_LEVEL="DEBUG"
|
||||
shift
|
||||
;;
|
||||
-q|--quiet)
|
||||
LOG_LEVEL="ERROR"
|
||||
shift
|
||||
;;
|
||||
-n|--dry-run)
|
||||
DRY_RUN=true
|
||||
shift
|
||||
;;
|
||||
-f|--force)
|
||||
FORCE=true
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
positional+=("$@")
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
die "Unknown option: $1" "$E_ARGS"
|
||||
;;
|
||||
*)
|
||||
positional+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# > Restore positional parameters
|
||||
set -- "${positional[@]}"
|
||||
|
||||
# > Validate required arguments
|
||||
if [[ $# -lt 1 ]]; then
|
||||
die "Missing required argument. Use --help for usage." "$E_ARGS"
|
||||
fi
|
||||
|
||||
# > Export parsed values for main()
|
||||
INPUT_ARG="$1"
|
||||
}
|
||||
|
||||
#===============================================================================
|
||||
# MAIN
|
||||
#===============================================================================
|
||||
|
||||
### Main entry point - orchestrates script execution
|
||||
### @param args array Command line arguments
|
||||
### @return 0 Success
|
||||
main() {
|
||||
check_bash_version
|
||||
parse_args "$@"
|
||||
check_dependencies
|
||||
setup_temp
|
||||
|
||||
log_info "Starting ${SCRIPT_NAME} v${VERSION}"
|
||||
[[ "${DRY_RUN}" == "true" ]] && log_warn "Running in dry-run mode"
|
||||
|
||||
do_work "${INPUT_ARG}"
|
||||
|
||||
log_info "Completed successfully"
|
||||
}
|
||||
|
||||
# > Entry point
|
||||
main "$@"
|
||||
|
||||
#===============================================================================
|
||||
# SELF-TEST EXAMPLES
|
||||
#===============================================================================
|
||||
# Run these commands to verify script behavior:
|
||||
#
|
||||
# 1. Show help:
|
||||
# ./minimal-template.sh --help
|
||||
#
|
||||
# 2. Dry-run mode:
|
||||
# ./minimal-template.sh --dry-run test-input
|
||||
#
|
||||
# 3. Invalid argument (expect exit 2):
|
||||
# ./minimal-template.sh --invalid-option
|
||||
#
|
||||
# 4. Missing argument (expect exit 2):
|
||||
# ./minimal-template.sh
|
||||
#
|
||||
# 5. Verbose mode:
|
||||
# ./minimal-template.sh --verbose test-input
|
||||
#===============================================================================
|
||||
121
1-AgentSkills/writing-bash-scripts/reference/code-structure.md
Normal file
121
1-AgentSkills/writing-bash-scripts/reference/code-structure.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Bash Script Code Structure Reference
|
||||
|
||||
## Section Order (固定顺序,不可打乱)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 1. SHEBANG + METADATA │
|
||||
│ #!/usr/bin/env bash │
|
||||
│ # Author / Version / License / Last Updated │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 2. ASCII CALL GRAPH │
|
||||
│ # main() │
|
||||
│ # ├── parse_args() │
|
||||
│ # ├── check_dependencies() │
|
||||
│ # ├── business_function_1() │
|
||||
│ # │ └── helper_function() │
|
||||
│ # └── cleanup() │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 3. GLOBAL CONSTANTS │
|
||||
│ readonly VERSION="1.0.0" │
|
||||
│ readonly SCRIPT_NAME="${0##*/}" │
|
||||
│ readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 4. STRICT MODE │
|
||||
│ set -Eeuo pipefail │
|
||||
│ IFS=$' \t\n' │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 5. CONFIGURABLE DEFAULTS │
|
||||
│ LOG_LEVEL="${LOG_LEVEL:-INFO}" │
|
||||
│ DRY_RUN=false │
|
||||
│ VERBOSE=false │
|
||||
│ FORCE=false │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 6. DEPENDENCY & ENVIRONMENT CHECKS │
|
||||
│ check_bash_version() │
|
||||
│ check_dependencies() │
|
||||
│ check_permissions() │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 7. LOGGING & ERROR HANDLING │
|
||||
│ log_debug() / log_info() / log_warn() / log_error() │
|
||||
│ die() │
|
||||
│ run_cmd() │
|
||||
│ cleanup() │
|
||||
│ trap setup │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 8. BUSINESS FUNCTIONS │
|
||||
│ (grouped by domain, each <50 lines) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 9. MAIN + ENTRY │
|
||||
│ main() { parse_args; check_deps; do_work; } │
|
||||
│ main "$@" │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Strict Mode Explained
|
||||
|
||||
```bash
|
||||
set -E # ERR trap inherited by functions
|
||||
set -e # Exit on error
|
||||
set -u # Error on unset variables
|
||||
set -o pipefail # Pipe fails if any command fails
|
||||
```
|
||||
|
||||
Combined: `set -Eeuo pipefail`
|
||||
|
||||
## IFS Safety
|
||||
|
||||
```bash
|
||||
# Default safe IFS
|
||||
IFS=$' \t\n'
|
||||
|
||||
# When processing CSV or custom delimiter, use local override:
|
||||
local IFS=','
|
||||
read -ra fields <<< "$line"
|
||||
```
|
||||
|
||||
## Variable Quoting Rules
|
||||
|
||||
| Context | Correct | Wrong |
|
||||
|---------|---------|-------|
|
||||
| Assignment | `var="$value"` | `var=$value` |
|
||||
| Command arg | `cmd "$file"` | `cmd $file` |
|
||||
| Array expansion | `"${arr[@]}"` | `${arr[@]}` |
|
||||
| Intentional splitting | `$unquoted # > reason` | (must comment) |
|
||||
|
||||
## Readonly Constants Pattern
|
||||
|
||||
```bash
|
||||
# Script metadata
|
||||
readonly VERSION="1.0.0"
|
||||
readonly SCRIPT_NAME="${0##*/}"
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Exit codes
|
||||
readonly E_SUCCESS=0
|
||||
readonly E_GENERAL=1
|
||||
readonly E_ARGS=2
|
||||
readonly E_DEPS=3
|
||||
readonly E_PERM=4
|
||||
readonly E_NOTFOUND=5
|
||||
```
|
||||
|
||||
## Temp Directory Pattern
|
||||
|
||||
```bash
|
||||
# Create temp dir with automatic cleanup
|
||||
TEMP_DIR=""
|
||||
|
||||
setup_temp() {
|
||||
TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/${SCRIPT_NAME}.XXXXXX")"
|
||||
readonly TEMP_DIR
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "${TEMP_DIR:-}" && -d "$TEMP_DIR" ]]; then
|
||||
rm -rf "$TEMP_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
trap cleanup EXIT ERR INT TERM
|
||||
```
|
||||
99
1-AgentSkills/writing-bash-scripts/reference/exit-codes.md
Normal file
99
1-AgentSkills/writing-bash-scripts/reference/exit-codes.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Exit Codes Reference
|
||||
|
||||
## Standard Exit Codes (必须遵循)
|
||||
|
||||
| Code | Constant | Meaning | Use Case |
|
||||
|------|----------|---------|----------|
|
||||
| 0 | `E_SUCCESS` | Success | Normal completion |
|
||||
| 1 | `E_GENERAL` | General error | Catch-all for unspecified errors |
|
||||
| 2 | `E_ARGS` | Invalid arguments | Wrong number, invalid format, unknown option |
|
||||
| 3 | `E_DEPS` | Missing dependency | Required command not found |
|
||||
| 4 | `E_PERM` | Permission denied | Cannot read/write/execute required resource |
|
||||
| 5 | `E_NOTFOUND` | Resource not found | File, directory, or resource doesn't exist |
|
||||
|
||||
## Extended Exit Codes (按需选用)
|
||||
|
||||
| Code | Constant | Meaning | Use Case |
|
||||
|------|----------|---------|----------|
|
||||
| 6 | `E_CONFIG` | Configuration error | Invalid or missing config file |
|
||||
| 7 | `E_NETWORK` | Network error | Connection failed, timeout |
|
||||
| 8 | `E_TIMEOUT` | Operation timeout | Command exceeded time limit |
|
||||
| 9 | `E_LOCK` | Lock acquisition failed | Cannot acquire file/process lock |
|
||||
| 10 | `E_STATE` | Invalid state | Precondition not met |
|
||||
|
||||
## Reserved Exit Codes (不要使用)
|
||||
|
||||
| Code | Reserved By | Meaning |
|
||||
|------|-------------|---------|
|
||||
| 126 | Shell | Command found but not executable |
|
||||
| 127 | Shell | Command not found |
|
||||
| 128 | Shell | Invalid exit code (exit only takes 0-255) |
|
||||
| 128+N | Shell | Fatal signal N (e.g., 130 = SIGINT, 137 = SIGKILL, 143 = SIGTERM) |
|
||||
| 255 | Shell | Exit code out of range |
|
||||
|
||||
## Declaration Pattern
|
||||
|
||||
```bash
|
||||
# Exit codes (declare at top, after shebang)
|
||||
readonly E_SUCCESS=0
|
||||
readonly E_GENERAL=1
|
||||
readonly E_ARGS=2
|
||||
readonly E_DEPS=3
|
||||
readonly E_PERM=4
|
||||
readonly E_NOTFOUND=5
|
||||
readonly E_CONFIG=6
|
||||
readonly E_NETWORK=7
|
||||
readonly E_TIMEOUT=8
|
||||
readonly E_LOCK=9
|
||||
readonly E_STATE=10
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
```bash
|
||||
# Argument validation
|
||||
[[ $# -ge 1 ]] || die "Missing required argument" "$E_ARGS"
|
||||
|
||||
# Dependency check
|
||||
command -v jq &>/dev/null || die "jq is required" "$E_DEPS"
|
||||
|
||||
# Permission check
|
||||
[[ -w "$output_dir" ]] || die "Cannot write to: $output_dir" "$E_PERM"
|
||||
|
||||
# File existence
|
||||
[[ -f "$config_file" ]] || die "Config not found: $config_file" "$E_NOTFOUND"
|
||||
|
||||
# Network error (with retry)
|
||||
curl -sf "$url" || die "Failed to fetch: $url" "$E_NETWORK"
|
||||
```
|
||||
|
||||
## Exit Code Ranges by Category
|
||||
|
||||
| Range | Category | Description |
|
||||
|-------|----------|-------------|
|
||||
| 0 | Success | All operations completed |
|
||||
| 1-10 | Application errors | Defined by script |
|
||||
| 11-63 | Reserved | For future application use |
|
||||
| 64-78 | BSD sysexits.h | Standard Unix exit codes |
|
||||
| 79-125 | Reserved | For future use |
|
||||
| 126-255 | Shell reserved | Do not use |
|
||||
|
||||
## sysexits.h Reference (可选,用于更严格的标准化)
|
||||
|
||||
| Code | Name | Meaning |
|
||||
|------|------|---------|
|
||||
| 64 | EX_USAGE | Command line usage error |
|
||||
| 65 | EX_DATAERR | Data format error |
|
||||
| 66 | EX_NOINPUT | Cannot open input |
|
||||
| 67 | EX_NOUSER | Addressee unknown |
|
||||
| 68 | EX_NOHOST | Host name unknown |
|
||||
| 69 | EX_UNAVAILABLE | Service unavailable |
|
||||
| 70 | EX_SOFTWARE | Internal software error |
|
||||
| 71 | EX_OSERR | System error |
|
||||
| 72 | EX_OSFILE | Critical OS file missing |
|
||||
| 73 | EX_CANTCREAT | Can't create output file |
|
||||
| 74 | EX_IOERR | I/O error |
|
||||
| 75 | EX_TEMPFAIL | Temporary failure; retry |
|
||||
| 76 | EX_PROTOCOL | Protocol error |
|
||||
| 77 | EX_NOPERM | Permission denied |
|
||||
| 78 | EX_CONFIG | Configuration error |
|
||||
@@ -0,0 +1,187 @@
|
||||
# Function Documentation Template
|
||||
|
||||
## Required Doc Block Format
|
||||
|
||||
Every function MUST have this header (缺一不可):
|
||||
|
||||
```bash
|
||||
### <One-line功能描述,动词开头>
|
||||
### @param <param_name> <type> <用途说明>
|
||||
### @param <param_name> <type> <用途说明>
|
||||
### @return <exit_code> <状态描述>
|
||||
### @require <依赖项/命令/权限/环境变量>
|
||||
### @side_effect <对文件/网络/系统的影响> (可选,有副作用时必填)
|
||||
function_name() {
|
||||
local param1="$1"
|
||||
local param2="${2:-default}"
|
||||
|
||||
# Implementation
|
||||
}
|
||||
```
|
||||
|
||||
## Type Annotations
|
||||
|
||||
| Type | Description | Example |
|
||||
|------|-------------|---------|
|
||||
| `string` | Any text | `@param name string User's name` |
|
||||
| `int` | Integer number | `@param count int Number of retries` |
|
||||
| `bool` | true/false | `@param verbose bool Enable verbose mode` |
|
||||
| `path` | File/directory path | `@param config path Path to config file` |
|
||||
| `array` | Bash array | `@param files array List of input files` |
|
||||
| `fd` | File descriptor | `@param logfd fd File descriptor for logging` |
|
||||
|
||||
## Complete Example
|
||||
|
||||
```bash
|
||||
### Validate that a file exists and is readable
|
||||
### @param file_path path Absolute or relative path to validate
|
||||
### @param allow_empty bool Whether empty files are valid (default: false)
|
||||
### @return 0 File is valid and readable
|
||||
### @return 1 File does not exist
|
||||
### @return 2 File is not readable
|
||||
### @return 3 File is empty (when allow_empty=false)
|
||||
### @require read permission on file_path
|
||||
validate_file() {
|
||||
local file_path="$1"
|
||||
local allow_empty="${2:-false}"
|
||||
|
||||
# > Check existence first (most common failure)
|
||||
if [[ ! -e "$file_path" ]]; then
|
||||
log_error "File not found: $file_path"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# > Check readability
|
||||
if [[ ! -r "$file_path" ]]; then
|
||||
log_error "File not readable: $file_path"
|
||||
return 2
|
||||
fi
|
||||
|
||||
# > Check empty (only if not allowed)
|
||||
if [[ "$allow_empty" != "true" && ! -s "$file_path" ]]; then
|
||||
log_error "File is empty: $file_path"
|
||||
return 3
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
## Logging Functions Template
|
||||
|
||||
```bash
|
||||
### Log message at DEBUG level
|
||||
### @param message string Message to log
|
||||
### @return 0 Always succeeds
|
||||
log_debug() {
|
||||
[[ "${LOG_LEVEL:-INFO}" == "DEBUG" ]] || return 0
|
||||
printf '[%s] [DEBUG] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2
|
||||
}
|
||||
|
||||
### Log message at INFO level
|
||||
### @param message string Message to log
|
||||
### @return 0 Always succeeds
|
||||
log_info() {
|
||||
[[ "${LOG_LEVEL:-INFO}" =~ ^(DEBUG|INFO)$ ]] || return 0
|
||||
printf '[%s] [INFO] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2
|
||||
}
|
||||
|
||||
### Log message at WARN level
|
||||
### @param message string Message to log
|
||||
### @return 0 Always succeeds
|
||||
log_warn() {
|
||||
[[ "${LOG_LEVEL:-INFO}" =~ ^(DEBUG|INFO|WARN)$ ]] || return 0
|
||||
printf '[%s] [WARN] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2
|
||||
}
|
||||
|
||||
### Log message at ERROR level
|
||||
### @param message string Message to log
|
||||
### @return 0 Always succeeds
|
||||
log_error() {
|
||||
printf '[%s] [ERROR] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2
|
||||
}
|
||||
```
|
||||
|
||||
## Die Function Template
|
||||
|
||||
```bash
|
||||
### Exit with error message and code, including location info
|
||||
### @param message string Error message
|
||||
### @param exit_code int Exit code (default: 1)
|
||||
### @return never Returns (exits script)
|
||||
### @side_effect Terminates script execution
|
||||
die() {
|
||||
local message="$1"
|
||||
local exit_code="${2:-1}"
|
||||
local caller_info=""
|
||||
|
||||
# > Build stack trace for debugging
|
||||
if [[ "${BASH_LINENO[0]:-0}" -gt 0 ]]; then
|
||||
caller_info=" (${FUNCNAME[1]:-main}:${BASH_LINENO[0]:-?})"
|
||||
fi
|
||||
|
||||
log_error "${message}${caller_info}"
|
||||
exit "$exit_code"
|
||||
}
|
||||
```
|
||||
|
||||
## Run Command Wrapper Template
|
||||
|
||||
```bash
|
||||
### Execute command with dry-run support and error handling
|
||||
### @param cmd string Command to execute (as array: "${cmd[@]}")
|
||||
### @return 0 Command succeeded
|
||||
### @return 1 Command failed
|
||||
### @side_effect Executes external command (unless DRY_RUN=true)
|
||||
run_cmd() {
|
||||
local -a cmd=("$@")
|
||||
|
||||
if [[ "${DRY_RUN:-false}" == "true" ]]; then
|
||||
log_info "[DRY-RUN] Would execute: ${cmd[*]}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "${VERBOSE:-false}" == "true" ]]; then
|
||||
log_debug "Executing: ${cmd[*]}"
|
||||
fi
|
||||
|
||||
if ! "${cmd[@]}"; then
|
||||
log_error "Command failed: ${cmd[*]}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
## Input Validation Pattern
|
||||
|
||||
```bash
|
||||
### Validate path argument
|
||||
### @param path path Path to validate
|
||||
### @param must_exist bool Path must exist (default: true)
|
||||
### @param must_be_writable bool Path must be writable (default: false)
|
||||
validate_path() {
|
||||
local path="$1"
|
||||
local must_exist="${2:-true}"
|
||||
local must_be_writable="${3:-false}"
|
||||
|
||||
# > Reject empty paths
|
||||
[[ -n "$path" ]] || die "Path cannot be empty" 2
|
||||
|
||||
# > Resolve to absolute path
|
||||
if [[ "$path" != /* ]]; then
|
||||
path="$(cd "$(dirname "$path")" 2>/dev/null && pwd)/$(basename "$path")"
|
||||
fi
|
||||
|
||||
if [[ "$must_exist" == "true" && ! -e "$path" ]]; then
|
||||
die "Path does not exist: $path" 5
|
||||
fi
|
||||
|
||||
if [[ "$must_be_writable" == "true" && ! -w "$path" ]]; then
|
||||
die "Path not writable: $path" 4
|
||||
fi
|
||||
|
||||
printf '%s' "$path"
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env bash
|
||||
#===============================================================================
|
||||
# Script Name : shellcheck-wrapper.sh
|
||||
# Description : Wrapper for ShellCheck with project defaults
|
||||
# Version : 1.0.0
|
||||
#===============================================================================
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
readonly SCRIPT_NAME="${0##*/}"
|
||||
|
||||
### Display usage
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ${SCRIPT_NAME} <script.sh> [shellcheck-options...]
|
||||
|
||||
Runs ShellCheck with recommended settings for production Bash scripts.
|
||||
|
||||
Default flags applied:
|
||||
-x Follow source statements
|
||||
-s bash Shell dialect: bash
|
||||
-S style Minimum severity: style (catch everything)
|
||||
|
||||
Examples:
|
||||
${SCRIPT_NAME} myscript.sh
|
||||
${SCRIPT_NAME} myscript.sh -S warning # Only warnings and above
|
||||
${SCRIPT_NAME} *.sh # Check multiple files
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
### Check ShellCheck is installed
|
||||
check_shellcheck() {
|
||||
if ! command -v shellcheck &>/dev/null; then
|
||||
echo "ERROR: shellcheck not found. Install with:" >&2
|
||||
echo " Ubuntu/Debian: apt install shellcheck" >&2
|
||||
echo " macOS: brew install shellcheck" >&2
|
||||
echo " Windows: scoop install shellcheck" >&2
|
||||
exit 3
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
if [[ $# -lt 1 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
check_shellcheck
|
||||
|
||||
local script="$1"
|
||||
shift
|
||||
|
||||
if [[ ! -f "$script" ]]; then
|
||||
echo "ERROR: File not found: $script" >&2
|
||||
exit 5
|
||||
fi
|
||||
|
||||
echo "Running ShellCheck on: $script"
|
||||
echo "========================================"
|
||||
|
||||
# > Run with defaults + any user-provided options
|
||||
# shellcheck disable=SC2086
|
||||
shellcheck -x -s bash -S style "$@" "$script"
|
||||
|
||||
local exit_code=$?
|
||||
|
||||
if [[ $exit_code -eq 0 ]]; then
|
||||
echo "========================================"
|
||||
echo "✓ No issues found"
|
||||
else
|
||||
echo "========================================"
|
||||
echo "✗ ShellCheck found issues (exit code: $exit_code)"
|
||||
fi
|
||||
|
||||
exit $exit_code
|
||||
}
|
||||
|
||||
main "$@"
|
||||
81
13-SHELL脚本/shell-prompt-2.md
Normal file
81
13-SHELL脚本/shell-prompt-2.md
Normal file
@@ -0,0 +1,81 @@
|
||||
你是一名资深 Bash Shell 工程师。请基于【功能需求】输出一份“可直接落地”的生产级脚本(单文件),并严格遵循以下工程规范与交付要求。
|
||||
|
||||
【功能需求】
|
||||
- (在此粘贴:目标、输入/输出、流程、约束、示例数据、成功/失败判定、是否需要远程执行/并发/幂等、目标系统等)
|
||||
|
||||
========================
|
||||
一、交付物与输出格式(必须满足)
|
||||
========================
|
||||
1) 交付物为“一个可运行的 Bash 脚本”,放在一个代码块中输出,包含:
|
||||
- shebang:#!/usr/bin/env bash
|
||||
- Bash 版本要求:Bash >= 5.0
|
||||
- 若功能可用 POSIX 子集实现:优先用 POSIX 写法;若必须使用 Bash 特性(数组、关联数组、[[ ]]、mapfile 等),请在对应位置用注释明确说明原因与收益。
|
||||
2) 脚本必须提供:
|
||||
- usage/help(-h/--help),包含示例
|
||||
- 参数解析(getopts 或等效安全方案),参数缺失/非法时给出可读错误
|
||||
- 清晰的退出码约定(0 成功;非 0 表示失败并可区分类型)
|
||||
3) 默认行为要求:
|
||||
- 安全默认值(不破坏系统、不覆盖关键文件;涉及写入/删除必须显式确认或提供 --force)
|
||||
- 支持 --dry-run(只打印将执行的动作,不实际执行)
|
||||
- 支持 --verbose / --quiet(或 LOG_LEVEL)
|
||||
4) 文档与可读性:
|
||||
- 关键步骤用 “# >” 行内注释解释意图(不是复述代码)
|
||||
- 在脚本顶部提供 ASCII 调用关系/流程图(call graph)
|
||||
|
||||
========================
|
||||
二、代码结构与工程规范(必须满足)
|
||||
========================
|
||||
1) 严格模式与防御性编程
|
||||
- set -Eeuo pipefail,并启用 errtrace(set -E)保证函数内错误可追踪
|
||||
- IFS 安全设置(如 IFS=$' \t\n' 或在局部处理输入时显式设定)
|
||||
- 禁止未引用变量、禁止不安全的 eval;所有变量引用必须加双引号(除非明确需要 word splitting,并解释原因)
|
||||
2) 模块化组织(建议分区,且顺序固定)
|
||||
- 元数据区(作者/版本/许可证/最后更新)
|
||||
- 全局常量区(readonly 常量;可配置项集中)
|
||||
- 依赖与环境检查区(命令存在性、权限、OS/发行版识别如需要)
|
||||
- 日志与错误处理区(统一 logger、die、assert、run_cmd)
|
||||
- 业务函数区(按领域分组,函数短小)
|
||||
- main() 与入口区(只做流程编排,不堆业务细节)
|
||||
3) 错误处理机制
|
||||
- 统一错误出口:die <msg> <exit_code>
|
||||
- trap:至少覆盖 ERR / INT / TERM / EXIT
|
||||
- cleanup:退出时清理临时文件/锁(用 mktemp 创建临时目录)
|
||||
- 错误信息必须包含:失败命令、行号、函数栈(尽可能)
|
||||
|
||||
========================
|
||||
三、函数设计标准(必须满足)
|
||||
========================
|
||||
1) 每个函数必须带“### 注释块”,格式如下(缺一不可):
|
||||
### <一句话功能描述>
|
||||
### @param <name> <type> <用途说明>
|
||||
### @return <exit_code> <状态描述>
|
||||
### @require <依赖项/命令/权限/环境>
|
||||
### @side_effect <可选:对文件/网络/系统的影响>
|
||||
2) 命名规范
|
||||
- 函数与变量使用 snake_case
|
||||
- 全局常量使用全大写 + 下划线(readonly)
|
||||
3) 输入校验
|
||||
- 所有外部输入(参数、文件、环境变量、命令输出)必须校验
|
||||
- 涉及路径:必须处理空值、相对/绝对、是否存在、是否可写、是否为符号链接(按需求决定策略)
|
||||
|
||||
========================
|
||||
四、日志与可观测性(必须满足)
|
||||
========================
|
||||
1) 统一日志函数:log_debug/log_info/log_warn/log_error
|
||||
- 日志格式包含:时间戳、级别、消息
|
||||
- 支持 LOG_LEVEL 控制输出(DEBUG/INFO/WARN/ERROR)
|
||||
2) run_cmd 包装器
|
||||
- 所有外部命令执行通过 run_cmd,支持 dry-run、错误捕获、可选重试(如需求涉及网络/不稳定操作)
|
||||
|
||||
========================
|
||||
五、质量保障与自检(必须满足)
|
||||
========================
|
||||
1) 脚本需满足 ShellCheck(如必须禁用某条规则,必须用 # shellcheck disable=SCxxxx 并解释原因)
|
||||
2) 在脚本末尾或注释区给出“最小自测方法”
|
||||
- 至少给出 3 条示例命令覆盖:正常路径、参数错误、dry-run
|
||||
|
||||
========================
|
||||
六、输出要求(强约束)
|
||||
========================
|
||||
- 只输出脚本代码(一个代码块),不要输出额外解释性长文;必要说明写在脚本注释里
|
||||
- 若【功能需求】存在歧义:请做“合理默认”,并把假设写在脚本头部的 Assumptions 注释段
|
||||
18
13-SHELL脚本/shell-prompt.md
Normal file
18
13-SHELL脚本/shell-prompt.md
Normal file
@@ -0,0 +1,18 @@
|
||||
请以Bash Shell脚本高级开发工程师的身份,严格遵循以下编程规范实现指定功能:
|
||||
|
||||
1. 代码结构规范
|
||||
- 符合POSIX标准与Bash最佳实践(v5.0+)
|
||||
- 实现清晰的模块划分和函数封装
|
||||
- 采用防御性编程策略处理异常情况
|
||||
- 包含完善的错误处理机制(trap、set -euo pipefail)
|
||||
2. 函数设计标准
|
||||
- 函数声明需包含: 功能描述段(使用###注释块) 参数说明:@param <变量名> <数据类型> <用途说明> 返回值说明:@return <退出码> <状态描述> 环境依赖:@require <依赖项>
|
||||
- 函数参数命名采用snake_case格式,体现语义化特征
|
||||
3. 文档规范
|
||||
- 主脚本头部包含: 元数据声明(作者、版本、许可证) 全局常量定义区 模块依赖说明
|
||||
- 关键算法步骤添加行内注释(# > 开头)
|
||||
- 维护完整的函数调用关系图(使用ASCII流程图)
|
||||
4. 质量保障
|
||||
- 通过ShellCheck进行静态检测
|
||||
- 统一的日志函数,实现详细的日志分级输出(DEBUG/INFO/WARN/ERROR)
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
## 输入
|
||||
- 源文档路径(用于动态注入内容):
|
||||
@C:\Users\wddsh\Documents\IdeaProjects\ProjectAGiPrompt\1-Vue3项目\vue3-typescript-style-v2.md
|
||||
@C:\Users\wddsh\Documents\IdeaProjects\ProjectAGiPrompt\1-Vue3项目\frontend-design-skill.md 请重点参考此SKILL的写法
|
||||
@C:\Users\wddsh\Documents\IdeaProjects\ProjectAGiPrompt\13-SHELL脚本\shell-prompt-2.md
|
||||
- 你将从该源文档中提炼“领域特定规则、具体操作步骤、可执行检查清单”,删除常识性解释。
|
||||
|
||||
> 若无法读取文件,则明确指出“缺少源文档内容”,并输出你需要用户提供的最小信息清单(不要继续臆造细节)。
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="GENERAL_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
|
||||
Reference in New Issue
Block a user