Install
npx skillscat add chaterm/terminal-skills/shell-scripting Install via the SkillsCat registry.
About this skill
This skill enables writing, debugging, and maintaining Bash shell scripts for automation tasks. It solves the problem of manual repetitive operations by enabling scripted workflows. Use it when automating file manipulation, system monitoring, or data processing tasks in Linux environments.
SKILL.md
Shell 脚本编写
概述
Bash 脚本编写、调试、最佳实践等技能。
基础语法
脚本结构
#!/bin/bash
# 脚本描述
# Author: name
# Date: 2024-01-01
set -euo pipefail # 严格模式
# 变量定义
VAR="value"
readonly CONST="constant"
# 主逻辑
main() {
echo "Hello, World!"
}
main "$@"变量
# 定义变量
name="value"
name='literal value' # 不解析变量
# 使用变量
echo $name
echo ${name}
echo "${name}_suffix"
# 默认值
${var:-default} # 未设置时使用默认值
${var:=default} # 未设置时赋值并使用
${var:+value} # 已设置时使用 value
${var:?error message} # 未设置时报错
# 字符串操作
${#var} # 长度
${var:0:5} # 子串
${var#pattern} # 删除前缀
${var%pattern} # 删除后缀
${var/old/new} # 替换数组
# 定义数组
arr=(a b c d)
arr[0]="first"
# 访问数组
${arr[0]} # 第一个元素
${arr[@]} # 所有元素
${#arr[@]} # 数组长度
${!arr[@]} # 所有索引
# 遍历数组
for item in "${arr[@]}"; do
echo "$item"
done流程控制
条件判断
# if 语句
if [[ condition ]]; then
commands
elif [[ condition ]]; then
commands
else
commands
fi
# 条件表达式
[[ -f file ]] # 文件存在
[[ -d dir ]] # 目录存在
[[ -z "$var" ]] # 变量为空
[[ -n "$var" ]] # 变量非空
[[ "$a" == "$b" ]] # 字符串相等
[[ "$a" != "$b" ]] # 字符串不等
[[ $a -eq $b ]] # 数字相等
[[ $a -lt $b ]] # 小于
[[ $a -gt $b ]] # 大于
# 逻辑运算
[[ cond1 && cond2 ]] # 与
[[ cond1 || cond2 ]] # 或
[[ ! cond ]] # 非循环
# for 循环
for i in 1 2 3 4 5; do
echo $i
done
for i in {1..10}; do
echo $i
done
for ((i=0; i<10; i++)); do
echo $i
done
for file in *.txt; do
echo "$file"
done
# while 循环
while [[ condition ]]; do
commands
done
# 读取文件
while IFS= read -r line; do
echo "$line"
done < file.txt
# until 循环
until [[ condition ]]; do
commands
donecase 语句
case "$var" in
pattern1)
commands
;;
pattern2|pattern3)
commands
;;
*)
default commands
;;
esac函数
定义函数
# 方式1
function_name() {
local var="local variable"
echo "Arguments: $@"
echo "First arg: $1"
echo "Arg count: $#"
return 0
}
# 方式2
function function_name {
commands
}
# 调用函数
function_name arg1 arg2
# 获取返回值
result=$(function_name)常用函数模板
# 日志函数
log() {
local level=$1
shift
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*"
}
log INFO "This is info message"
log ERROR "This is error message"
# 错误处理
die() {
echo "ERROR: $*" >&2
exit 1
}
# 确认函数
confirm() {
read -p "$1 [y/N] " response
[[ "$response" =~ ^[Yy]$ ]]
}
if confirm "Continue?"; then
echo "Proceeding..."
fi输入输出
读取输入
# 读取用户输入
read -p "Enter name: " name
read -sp "Enter password: " password # 隐藏输入
read -t 10 -p "Quick! " answer # 超时
# 读取文件
while IFS= read -r line; do
echo "$line"
done < file.txt重定向
# 输出重定向
command > file # 覆盖
command >> file # 追加
command 2> error.log # 错误输出
command > file 2>&1 # 合并输出
command &> file # 同上
# 输入重定向
command < file
# Here Document
cat << EOF
多行文本
变量: $var
EOF
cat << 'EOF' # 不解析变量
原始文本
EOF调试技巧
调试选项
# 启用调试
set -x # 打印执行的命令
set -v # 打印读取的行
set -e # 出错即退出
set -u # 未定义变量报错
set -o pipefail # 管道错误传递
# 组合使用
set -euxo pipefail
# 调试特定部分
set -x
# 调试代码
set +x调试工具
# 语法检查
bash -n script.sh
# 调试运行
bash -x script.sh
# shellcheck 静态分析
shellcheck script.sh最佳实践
脚本模板
#!/bin/bash
#
# Script: script_name.sh
# Description: Brief description
# Author: Your Name
# Date: 2024-01-01
#
set -euo pipefail
# Constants
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "$0")"
# Logging
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
error() { echo "[ERROR] $*" >&2; }
die() { error "$*"; exit 1; }
# Usage
usage() {
cat << EOF
Usage: $SCRIPT_NAME [options] <arguments>
Options:
-h, --help Show this help message
-v, --verbose Enable verbose mode
Examples:
$SCRIPT_NAME -v input.txt
EOF
}
# Parse arguments
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
usage
exit 0
;;
-v|--verbose)
VERBOSE=true
shift
;;
*)
ARGS+=("$1")
shift
;;
esac
done
}
# Main
main() {
parse_args "$@"
# Your logic here
log "Starting $SCRIPT_NAME"
}
main "$@"故障排查
| 问题 | 解决方法 |
|---|---|
| 语法错误 | bash -n script.sh 检查 |
| 变量未定义 | 使用 set -u 或 ${var:-} |
| 空格问题 | 变量加引号 "$var" |
| 管道错误被忽略 | 使用 set -o pipefail |
| 调试困难 | 使用 set -x 或 shellcheck |