shell-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseShell Scripting Best Practices
Shell脚本最佳实践
Comprehensive guide to writing robust, maintainable, and secure shell scripts following modern best practices.
本指南全面介绍如何遵循现代最佳实践编写健壮、可维护且安全的Shell脚本。
Script Foundation
脚本基础
Shebang Selection
Shebang选择
Choose the appropriate shebang for your needs:
bash
undefined根据需求选择合适的shebang:
bash
undefinedPortable bash (recommended)
Portable bash (recommended)
#!/usr/bin/env bash
#!/usr/bin/env bash
Direct bash path (faster, less portable)
Direct bash path (faster, less portable)
#!/bin/bash
#!/bin/bash
POSIX-compliant shell (most portable)
POSIX-compliant shell (most portable)
#!/bin/sh
#!/bin/sh
Specific shell version
Specific shell version
#!/usr/bin/env bash
#!/usr/bin/env bash
Requires Bash 4.0+
Requires Bash 4.0+
undefinedundefinedStrict Mode
严格模式
Always enable strict error handling:
bash
#!/usr/bin/env bash
set -euo pipefail始终启用严格的错误处理:
bash
#!/usr/bin/env bash
set -euo pipefailWhat these do:
What these do:
-e: Exit immediately on command failure
-e: Exit immediately on command failure
-u: Treat unset variables as errors
-u: Treat unset variables as errors
-o pipefail: Pipeline fails if any command fails
-o pipefail: Pipeline fails if any command fails
For debugging, add:
```bash
set -x # Print commands as they execute
如需调试,添加以下配置:
```bash
set -x # Print commands as they executeScript Header Template
脚本头部模板
bash
#!/usr/bin/env bash
set -euo pipefailbash
#!/usr/bin/env bash
set -euo pipefailScript: script-name.sh
Script: script-name.sh
Description: Brief description of what this script does
Description: Brief description of what this script does
Usage: ./script-name.sh [options] <arguments>
Usage: ./script-name.sh [options] <arguments>
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
undefinedreadonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
undefinedVariable Handling
变量处理
Always Quote Variables
始终给变量加引号
Prevents word splitting and glob expansion:
bash
undefined防止单词拆分和通配符扩展:
bash
undefinedGood
Good
echo "$variable"
cp "$source" "$destination"
if [ -f "$file" ]; then
echo "$variable"
cp "$source" "$destination"
if [ -f "$file" ]; then
Bad - can break on spaces/special chars
Bad - can break on spaces/special chars
echo $variable
cp $source $destination
if [ -f $file ]; then
undefinedecho $variable
cp $source $destination
if [ -f $file ]; then
undefinedUse Meaningful Names
使用有意义的变量名
bash
undefinedbash
undefinedGood
Good
readonly config_file="/etc/app/config.yml"
local user_input="$1"
declare -a log_files=()
readonly config_file="/etc/app/config.yml"
local user_input="$1"
declare -a log_files=()
Bad
Bad
readonly f="/etc/app/config.yml"
local x="$1"
declare -a arr=()
undefinedreadonly f="/etc/app/config.yml"
local x="$1"
declare -a arr=()
undefinedDefault Values
默认值设置
bash
undefinedbash
undefinedUse default if unset
未设置时使用默认值
name="${NAME:-default_value}"
name="${NAME:-default_value}"
Use default if unset or empty
未设置或为空时使用默认值
name="${NAME:-}"
name="${NAME:-}"
Assign default if unset
未设置时赋值默认值
: "${NAME:=default_value}"
: "${NAME:=default_value}"
Error if unset (with message)
未设置时抛出错误(带提示信息)
: "${REQUIRED_VAR:?Error: REQUIRED_VAR must be set}"
undefined: "${REQUIRED_VAR:?Error: REQUIRED_VAR must be set}"
undefinedReadonly and Local
只读变量与局部变量
bash
undefinedbash
undefinedConstants
常量
readonly MAX_RETRIES=3
readonly CONFIG_DIR="/etc/myapp"
readonly MAX_RETRIES=3
readonly CONFIG_DIR="/etc/myapp"
Function-local variables
函数局部变量
my_function() {
local input="$1"
local result=""
# ...
}
undefinedmy_function() {
local input="$1"
local result=""
# ...
}
undefinedError Handling
错误处理
Exit Codes
退出码
Use meaningful exit codes:
bash
undefined使用有意义的退出码:
bash
undefinedStandard codes
标准退出码
readonly EXIT_SUCCESS=0
readonly EXIT_FAILURE=1
readonly EXIT_INVALID_ARGS=2
readonly EXIT_NOT_FOUND=3
readonly EXIT_SUCCESS=0
readonly EXIT_FAILURE=1
readonly EXIT_INVALID_ARGS=2
readonly EXIT_NOT_FOUND=3
Exit with code
带退出码退出
exit "$EXIT_FAILURE"
undefinedexit "$EXIT_FAILURE"
undefinedTrap for Cleanup
清理操作陷阱
bash
cleanup() {
local exit_code=$?
# Clean up temporary files
rm -f "${temp_file:-}"
# Restore state if needed
exit "$exit_code"
}
trap cleanup EXITbash
cleanup() {
local exit_code=$?
# 清理临时文件
rm -f "${temp_file:-}"
# 如有需要恢复状态
exit "$exit_code"
}
trap cleanup EXITScript continues...
脚本继续执行...
temp_file=$(mktemp)
undefinedtemp_file=$(mktemp)
undefinedError Messages
错误信息
bash
error() {
echo "ERROR: $*" >&2
}
warn() {
echo "WARNING: $*" >&2
}
die() {
error "$@"
exit 1
}bash
error() {
echo "ERROR: $*" >&2
}
warn() {
echo "WARNING: $*" >&2
}
die() {
error "$@"
exit 1
}Usage
使用示例
[[ -f "$config_file" ]] || die "Config file not found: $config_file"
undefined[[ -f "$config_file" ]] || die "Config file not found: $config_file"
undefinedValidate Inputs
输入验证
bash
validate_args() {
if [[ $# -lt 1 ]]; then
die "Usage: $SCRIPT_NAME <input_file>"
fi
local input_file="$1"
[[ -f "$input_file" ]] || die "File not found: $input_file"
[[ -r "$input_file" ]] || die "File not readable: $input_file"
}bash
validate_args() {
if [[ $# -lt 1 ]]; then
die "Usage: $SCRIPT_NAME <input_file>"
fi
local input_file="$1"
[[ -f "$input_file" ]] || die "File not found: $input_file"
[[ -r "$input_file" ]] || die "File not readable: $input_file"
}Functions
函数
Function Definition
函数定义
bash
undefinedbash
undefinedDocument functions
函数文档
Process a log file and extract errors
处理日志文件并提取错误信息
Arguments:
参数:
$1 - Path to log file
$1 - 日志文件路径
$2 - Output directory (optional, default: ./output)
$2 - 输出目录(可选,默认值:./output)
Returns:
返回值:
0 on success, 1 on failure
执行成功返回0,失败返回1
process_log() {
local log_file="$1"
local output_dir="${2:-./output}"
[[ -f "$log_file" ]] || return 1
grep -i "error" "$log_file" > "$output_dir/errors.log"}
undefinedprocess_log() {
local log_file="$1"
local output_dir="${2:-./output}"
[[ -f "$log_file" ]] || return 1
grep -i "error" "$log_file" > "$output_dir/errors.log"}
undefinedReturn Values
返回值
bash
undefinedbash
undefinedReturn status
返回状态
is_valid() {
[[ -n "$1" && "$1" =~ ^[0-9]+$ ]]
}
if is_valid "$input"; then
echo "Valid"
fi
is_valid() {
[[ -n "$1" && "$1" =~ ^[0-9]+$ ]]
}
if is_valid "$input"; then
echo "Valid"
fi
Capture output
捕获输出
get_config_value() {
local key="$1"
grep "^${key}=" "$config_file" | cut -d= -f2
}
value=$(get_config_value "database_host")
undefinedget_config_value() {
local key="$1"
grep "^${key}=" "$config_file" | cut -d= -f2
}
value=$(get_config_value "database_host")
undefinedConditionals
条件判断
Use [[ ]] for Tests
使用[[ ]]进行测试
bash
undefinedbash
undefinedGood - [[ ]] is more powerful and safer
推荐 - [[ ]]功能更强大且更安全
if [[ -f "$file" ]]; then
if [[ "$string" == "value" ]]; then
if [[ "$string" =~ ^[0-9]+$ ]]; then
if [[ -f "$file" ]]; then
if [[ "$string" == "value" ]]; then
if [[ "$string" =~ ^[0-9]+$ ]]; then
Avoid - [ ] has limitations
避免使用 - [ ] 存在局限性
if [ -f "$file" ]; then
if [ "$string" = "value" ]; then
undefinedif [ -f "$file" ]; then
if [ "$string" = "value" ]; then
undefinedNumeric Comparisons
数值比较
bash
undefinedbash
undefinedUse (( )) for arithmetic
使用 (( )) 进行算术比较
if (( count > 10 )); then
if (( a == b )); then
if (( x >= 0 && x <= 100 )); then
if (( count > 10 )); then
if (( a == b )); then
if (( x >= 0 && x <= 100 )); then
Or -eq/-lt/-gt in [[ ]]
或在[[ ]]中使用-eq/-lt/-gt
if [[ "$count" -gt 10 ]]; then
undefinedif [[ "$count" -gt 10 ]]; then
undefinedString Comparisons
字符串比较
bash
undefinedbash
undefinedEquality
相等判断
if [[ "$str" == "value" ]]; then
if [[ "$str" == "value" ]]; then
Pattern matching
模式匹配
if [[ "$str" == *.txt ]]; then
if [[ "$str" == *.txt ]]; then
Regex matching
正则匹配
if [[ "$str" =~ ^[a-z]+$ ]]; then
if [[ "$str" =~ ^[a-z]+$ ]]; then
Empty/non-empty
空值/非空值判断
if [[ -z "$str" ]]; then # empty
if [[ -n "$str" ]]; then # non-empty
undefinedif [[ -z "$str" ]]; then # 空值
if [[ -n "$str" ]]; then # 非空值
undefinedLoops
循环
Iterate Over Files
遍历文件
bash
undefinedbash
undefinedGood - handles spaces in filenames
推荐 - 处理文件名中的空格
for file in *.txt; do
[[ -e "$file" ]] || continue # Skip if no matches
process "$file"
done
for file in *.txt; do
[[ -e "$file" ]] || continue # 无匹配项时跳过
process "$file"
done
With find for recursive
使用find进行递归遍历
while IFS= read -r -d '' file; do
process "$file"
done < <(find . -name "*.txt" -print0)
while IFS= read -r -d '' file; do
process "$file"
done < <(find . -name "*.txt" -print0)
Bad - breaks on spaces
不推荐 - 文件名含空格时会出错
for file in $(ls *.txt); do # Don't do this
undefinedfor file in $(ls *.txt); do # 不要这样做
undefinedRead Lines from File
读取文件行
bash
undefinedbash
undefinedCorrect - preserves whitespace
正确方式 - 保留空格
while IFS= read -r line; do
echo "$line"
done < "$filename"
while IFS= read -r line; do
echo "$line"
done < "$filename"
With process substitution
结合进程替换
while IFS= read -r line; do
echo "$line"
done < <(some_command)
undefinedwhile IFS= read -r line; do
echo "$line"
done < <(some_command)
undefinedIterate with Index
带索引遍历
bash
files=("one.txt" "two.txt" "three.txt")
for i in "${!files[@]}"; do
echo "Index $i: ${files[i]}"
donebash
files=("one.txt" "two.txt" "three.txt")
for i in "${!files[@]}"; do
echo "Index $i: ${files[i]}"
doneArrays
数组
Declaration and Usage
声明与使用
bash
undefinedbash
undefinedIndexed array
索引数组
declare -a files=()
files+=("file1.txt")
files+=("file2.txt")
declare -a files=()
files+=("file1.txt")
files+=("file2.txt")
Access all elements
访问所有元素
for f in "${files[@]}"; do
echo "$f"
done
for f in "${files[@]}"; do
echo "$f"
done
Array length
数组长度
echo "${#files[@]}"
echo "${#files[@]}"
Associative array (Bash 4+)
关联数组(Bash 4+)
declare -A config
config[host]="localhost"
config[port]="8080"
echo "${config[host]}"
undefineddeclare -A config
config[host]="localhost"
config[port]="8080"
echo "${config[host]}"
undefinedArray Best Practices
数组最佳实践
bash
undefinedbash
undefinedQuote expansions
引用数组扩展
"${array[@]}" # All elements, word-split
"${array[*]}" # All elements, single string
"${array[@]}" # 所有元素,按单词拆分
"${array[*]}" # 所有元素,合并为单个字符串
Check if empty
检查数组是否为空
if [[ ${#array[@]} -eq 0 ]]; then
echo "Empty array"
fi
if [[ ${#array[@]} -eq 0 ]]; then
echo "Empty array"
fi
Check for key (associative)
检查键是否存在(关联数组)
if [[ -v config[key] ]]; then
echo "Key exists"
fi
undefinedif [[ -v config[key] ]]; then
echo "Key exists"
fi
undefinedCommand Execution
命令执行
Check Command Existence
检查命令是否存在
bash
undefinedbash
undefinedPreferred method
推荐方法
if command -v docker &>/dev/null; then
echo "Docker is installed"
fi
if command -v docker &>/dev/null; then
echo "Docker is installed"
fi
In conditionals
在条件判断中使用
require_command() {
command -v "$1" &>/dev/null || die "Required command not found: $1"
}
require_command git
require_command docker
undefinedrequire_command() {
command -v "$1" &>/dev/null || die "Required command not found: $1"
}
require_command git
require_command docker
undefinedCapture Output and Status
捕获输出与状态
bash
undefinedbash
undefinedCapture output
捕获输出
output=$(some_command)
output=$(some_command)
Capture output and status
捕获输出与执行状态
if output=$(some_command 2>&1); then
echo "Success: $output"
else
echo "Failed: $output" >&2
fi
if output=$(some_command 2>&1); then
echo "Success: $output"
else
echo "Failed: $output" >&2
fi
Check status without output
不捕获输出仅检查状态
if some_command &>/dev/null; then
echo "Command succeeded"
fi
undefinedif some_command &>/dev/null; then
echo "Command succeeded"
fi
undefinedSafe Command Substitution
安全的命令替换
bash
undefinedbash
undefinedUse $() not backticks
使用$()而非反引号
result=$(command) # Good
result= # Avoid
commandresult=$(command) # 推荐
result= # 避免使用
commandNested substitution
嵌套替换
result=$(echo $(date)) # Works with $()
undefinedresult=$(echo $(date)) # $()支持嵌套
undefinedPortability
可移植性
POSIX vs Bash
POSIX vs Bash
| Feature | POSIX | Bash |
|---|---|---|
| Test syntax | | |
| Arrays | No | Yes |
| Yes | Yes |
| No | Yes |
| No | Yes |
| No | Yes |
| 特性 | POSIX | Bash |
|---|---|---|
| 测试语法 | | |
| 数组 | 不支持 | 支持 |
| 支持 | 支持 |
| 不支持 | 支持 |
| 不支持 | 支持 |
| 不支持 | 支持 |
Portable Alternatives
可移植替代方案
bash
undefinedbash
undefinedInstead of [[ ]], use [ ] with quotes
替代[[ ]],使用带引号的[ ]
if [ -f "$file" ]; then
if [ "$str" = "value" ]; then
if [ -f "$file" ]; then
if [ "$str" = "value" ]; then
Instead of (( )), use [ ] with -eq
替代(( )),使用带-eq的[ ]
if [ "$count" -gt 10 ]; then
if [ "$count" -gt 10 ]; then
Instead of ${var//pat/rep}
替代${var//pat/rep}
echo "$var" | sed 's/pat/rep/g'
echo "$var" | sed 's/pat/rep/g'
Instead of arrays, use space-separated strings
替代数组,使用空格分隔的字符串
files="one.txt two.txt three.txt"
for f in $files; do
echo "$f"
done
undefinedfiles="one.txt two.txt three.txt"
for f in $files; do
echo "$f"
done
undefinedSecurity
安全
Avoid Eval
避免使用Eval
bash
undefinedbash
undefinedBad - code injection risk
不推荐 - 存在代码注入风险
eval "$user_input"
eval "$user_input"
Better - use arrays for command building
推荐方式 - 使用数组构建命令
cmd=("grep" "-r" "$pattern" "$directory")
"${cmd[@]}"
undefinedcmd=("grep" "-r" "$pattern" "$directory")
"${cmd[@]}"
undefinedSanitize Inputs
输入清理
bash
undefinedbash
undefinedValidate expected format
验证预期格式
if [[ ! "$input" =~ ^[a-zA-Z0-9_-]+$ ]]; then
die "Invalid input format"
fi
if [[ ! "$input" =~ ^[a-zA-Z0-9_-]+$ ]]; then
die "Invalid input format"
fi
Escape for use in commands
转义后用于命令
escaped=$(printf '%q' "$input")
undefinedescaped=$(printf '%q' "$input")
undefinedTemporary Files
临时文件
bash
undefinedbash
undefinedSecure temp file creation
安全创建临时文件
temp_file=$(mktemp) || die "Failed to create temp file"
trap 'rm -f "$temp_file"' EXIT
temp_file=$(mktemp) || die "Failed to create temp file"
trap 'rm -f "$temp_file"' EXIT
Secure temp directory
安全创建临时目录
temp_dir=$(mktemp -d) || die "Failed to create temp dir"
trap 'rm -rf "$temp_dir"' EXIT
undefinedtemp_dir=$(mktemp -d) || die "Failed to create temp dir"
trap 'rm -rf "$temp_dir"' EXIT
undefinedLogging
日志
Basic Logging
基础日志
bash
readonly LOG_FILE="/var/log/myapp.log"
log() {
local level="$1"
shift
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*" | tee -a "$LOG_FILE"
}
log_info() { log "INFO" "$@"; }
log_warn() { log "WARN" "$@" >&2; }
log_error() { log "ERROR" "$@" >&2; }bash
readonly LOG_FILE="/var/log/myapp.log"
log() {
local level="$1"
shift
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*" | tee -a "$LOG_FILE"
}
log_info() { log "INFO" "$@"; }
log_warn() { log "WARN" "$@" >&2; }
log_error() { log "ERROR" "$@" >&2; }Usage
使用示例
log_info "Starting process"
log_error "Failed to connect"
undefinedlog_info "Starting process"
log_error "Failed to connect"
undefinedVerbose Mode
详细模式
bash
VERBOSE="${VERBOSE:-false}"
debug() {
if [[ "$VERBOSE" == "true" ]]; then
echo "DEBUG: $*" >&2
fi
}bash
VERBOSE="${VERBOSE:-false}"
debug() {
if [[ "$VERBOSE" == "true" ]]; then
echo "DEBUG: $*" >&2
fi
}Enable with: VERBOSE=true ./script.sh
通过以下方式启用:VERBOSE=true ./script.sh
undefinedundefinedComplete Script Template
完整脚本模板
bash
#!/usr/bin/env bash
set -euo pipefailbash
#!/usr/bin/env bash
set -euo pipefail=============================================================================
=============================================================================
Script: example.sh
Script: example.sh
Description: Template demonstrating shell best practices
Description: Template demonstrating shell best practices
Usage: ./example.sh [options] <input_file>
Usage: ./example.sh [options] <input_file>
=============================================================================
=============================================================================
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
Exit codes
Exit codes
readonly EXIT_SUCCESS=0
readonly EXIT_FAILURE=1
readonly EXIT_INVALID_ARGS=2
readonly EXIT_SUCCESS=0
readonly EXIT_FAILURE=1
readonly EXIT_INVALID_ARGS=2
Logging functions
Logging functions
log_info() { echo "[INFO] $"; }
log_error() { echo "[ERROR] $" >&2; }
log_info() { echo "[INFO] $"; }
log_error() { echo "[ERROR] $" >&2; }
Error handling
Error handling
die() {
log_error "$@"
exit "$EXIT_FAILURE"
}
cleanup() {
local exit_code=$?
rm -f "${temp_file:-}"
exit "$exit_code"
}
trap cleanup EXIT
die() {
log_error "$@"
exit "$EXIT_FAILURE"
}
cleanup() {
local exit_code=$?
rm -f "${temp_file:-}"
exit "$exit_code"
}
trap cleanup EXIT
Argument parsing
Argument parsing
usage() {
cat <<EOF
Usage: $SCRIPT_NAME [options] <input_file>
Options:
-h, --help Show this help message
-v, --verbose Enable verbose output
-o, --output Output directory (default: ./output)
Examples:
$SCRIPT_NAME input.txt
$SCRIPT_NAME -v -o /tmp/output input.txt
EOF
}
parse_args() {
local OPTIND opt
while getopts ":hvo:-:" opt; do
case "$opt" in
h) usage; exit "$EXIT_SUCCESS" ;;
v) VERBOSE=true ;;
o) OUTPUT_DIR="$OPTARG" ;;
-) case "$OPTARG" in
help) usage; exit "$EXIT_SUCCESS" ;;
verbose) VERBOSE=true ;;
output=) OUTPUT_DIR="${OPTARG#=}" ;;
*) die "Unknown option: --$OPTARG" ;;
esac ;;
:) die "Option -$OPTARG requires an argument" ;;
?) die "Unknown option: -$OPTARG" ;;
esac
done
shift $((OPTIND - 1))
if [[ $# -lt 1 ]]; then
usage
exit "$EXIT_INVALID_ARGS"
fi
INPUT_FILE="$1"}
usage() {
cat <<EOF
Usage: $SCRIPT_NAME [options] <input_file>
Options:
-h, --help Show this help message
-v, --verbose Enable verbose output
-o, --output Output directory (default: ./output)
Examples:
$SCRIPT_NAME input.txt
$SCRIPT_NAME -v -o /tmp/output input.txt
EOF
}
parse_args() {
local OPTIND opt
while getopts ":hvo:-:" opt; do
case "$opt" in
h) usage; exit "$EXIT_SUCCESS" ;;
v) VERBOSE=true ;;
o) OUTPUT_DIR="$OPTARG" ;;
-) case "$OPTARG" in
help) usage; exit "$EXIT_SUCCESS" ;;
verbose) VERBOSE=true ;;
output=) OUTPUT_DIR="${OPTARG#=}" ;;
*) die "Unknown option: --$OPTARG" ;;
esac ;;
:) die "Option -$OPTARG requires an argument" ;;
?) die "Unknown option: -$OPTARG" ;;
esac
done
shift $((OPTIND - 1))
if [[ $# -lt 1 ]]; then
usage
exit "$EXIT_INVALID_ARGS"
fi
INPUT_FILE="$1"}
Validate inputs
Validate inputs
validate() {
[[ -f "$INPUT_FILE" ]] || die "File not found: $INPUT_FILE"
[[ -r "$INPUT_FILE" ]] || die "File not readable: $INPUT_FILE"
mkdir -p "$OUTPUT_DIR" || die "Cannot create output directory"
}
validate() {
[[ -f "$INPUT_FILE" ]] || die "File not found: $INPUT_FILE"
[[ -r "$INPUT_FILE" ]] || die "File not readable: $INPUT_FILE"
mkdir -p "$OUTPUT_DIR" || die "Cannot create output directory"
}
Main logic
Main logic
main() {
# Defaults
VERBOSE="${VERBOSE:-false}"
OUTPUT_DIR="${OUTPUT_DIR:-./output}"
parse_args "$@"
validate
log_info "Processing $INPUT_FILE"
# ... main logic here ...
log_info "Done"}
main "$@"
undefinedmain() {
# Defaults
VERBOSE="${VERBOSE:-false}"
OUTPUT_DIR="${OUTPUT_DIR:-./output}"
parse_args "$@"
validate
log_info "Processing $INPUT_FILE"
# ... main logic here ...
log_info "Done"}
main "$@"
undefinedWhen to Use This Skill
何时使用本技能
- Writing new shell scripts from scratch
- Reviewing shell scripts for issues
- Refactoring legacy shell code
- Debugging script failures
- Improving script security
- Making scripts more portable
- Setting up proper error handling
- 从零开始编写新的Shell脚本
- 审查Shell脚本以发现问题
- 重构遗留Shell代码
- 调试脚本执行失败问题
- 提升脚本安全性
- 增强脚本可移植性
- 配置完善的错误处理机制