Shell 代码片段集合
收集常用的 Shell 代码片段,提高日常开发效率。
# 📋 目录
# pyenv
#!/usr/bin/env bash
set -e
[ -n "$PYENV_DEBUG" ] && set -x
program="${0##*/}"
export PYENV_ROOT="$HOME/.pyenv"
exec "/usr/local/opt/pyenv/bin/pyenv" exec "$program" "$@"
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
这是一个 Bash 脚本, 用于在 Pyenv 环境中执行 Python 程序。以下是对脚本的解释:
#!/usr/bin/env bash: 这是一个 Shebang 行, 它告诉操作系统使用 Bash 来执行这个脚本set -e: 这个命令将在脚本中启用"strict mode", 如果任何命令返回非零状态(失败), 脚本将立即退出[ -n "$PYENV_DEBUG" ] && set -x: 如果存在名为 PYENV_DEBUG 的环境变量并且其值非空, 则启用调试模式, 该模式会输出每个命令的执行program="${0##\*/}": 这一行提取了脚本文件的名称, 将其存储在变量 program 中export PYENV_ROOT="$HOME/.pyenv": 这一行设置了 PYENV_ROOT 环境变量, 指定 Pyenv 的根目录exec "/usr/local/opt/pyenv/bin/pyenv" exec "$program" "$@": 这是实际执行 Python 程序的命令。它使用 pyenv 工具来执行 Python 程序, "$program"表示要执行的Python程序的名称, "$@"表示传递给脚本的所有参数将传递给 Python 程序
总之, 这个脚本的目的是在 Pyenv 环境中执行 Python 程序, 它设置了一些环境变量, 并使用 pyenv 来确保 Python 程序在正确的环境中运行。如果你需要在 Pyenv 中运行 Python 程序, 并且希望通过脚本来管理它, 这个脚本可以派上用场
# v2ray 安装脚本学习
install-install-v2ray_study_shell_cache
# gen_random_string
gen_random_string() {
local length="${1:-16}" # 默认长度为 16(如果未提供)
# 如果 length 不是数字,或者小于等于 0,输出错误
if ! [[ "$length" =~ ^[0-9]+$ ]] || [ "$length" -le 0 ]; then
echo "Error: Please provide a valid positive integer for the length."
return 1
fi
# 直接使用 head -c 而不是 fold 和 head 的组合,减少处理步骤,提高效率
local random_string
random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' </dev/urandom | head -c "$length")
# 如果生成失败
if [ -z "$random_string" ]; then
echo "Error: Failed to generate random string." >&2
return 1
fi
echo "$random_string"
}
# 直接使用短路操作
gen_random_string "$@" || { echo "Failed to generate random string."; exit 1; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
LC_ALL=C:设置字符集为 C locale(标准 ASCII 字符集),确保字符处理的行为在不同系统下保持一致tr -dc 'a-zA-Z0-9':从/dev/urandom读取随机字节,并删除所有不在a-zA-Z0-9范围内的字符
# 文件操作
# 文件备份
# 安全备份文件
backup_file() {
local file="$1"
local backup_dir="${2:-./backup}"
if [ -f "$file" ]; then
mkdir -p "$backup_dir"
local timestamp=$(date +%Y%m%d_%H%M%S)
cp "$file" "$backup_dir/${file##*/}.bak.$timestamp"
echo "备份完成: $backup_dir/${file##*/}.bak.$timestamp"
else
echo "错误: 文件 '$file' 不存在" >&2
return 1
fi
}
# 使用示例
backup_file "/etc/nginx/nginx.conf" "/tmp/backup"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 批量文件重命名
# 批量重命名文件
batch_rename() {
local pattern="$1"
local replacement="$2"
local directory="${3:-.}"
for file in "$directory"/*; do
if [ -f "$file" ]; then
local basename=$(basename "$file")
local newname="${basename//$pattern/$replacement}"
if [ "$basename" != "$newname" ]; then
mv "$file" "$directory/$newname"
echo "重命名: $basename -> $newname"
fi
fi
done
}
# 使用示例:将 .txt 改为 .bak
batch_rename ".txt" ".bak" "/path/to/files"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 目录清理
# 清理空目录
cleanup_empty_dirs() {
local dir="${1:-.}"
find "$dir" -type d -empty -delete 2>/dev/null
echo "空目录清理完成"
}
# 清理临时文件
cleanup_temp_files() {
local dir="${1:-.}"
find "$dir" -name "*.tmp" -o -name "*.temp" -o -name "*~" | while read -r file; do
rm -f "$file"
echo "删除临时文件: $file"
done
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 系统信息获取
# 系统版本检测
# 检测操作系统类型
detect_os() {
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
echo "Linux"
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo "macOS"
elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]]; then
echo "Windows"
else
echo "Unknown: $OSTYPE"
fi
}
# 获取系统详细信息
get_system_info() {
echo "=== 系统信息 ==="
echo "操作系统: $(detect_os)"
echo "内核版本: $(uname -r)"
echo "架构: $(uname -m)"
echo "主机名: $(hostname)"
echo "用户: $(whoami)"
echo "Shell: $SHELL"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 磁盘空间检查
# 检查磁盘使用情况
check_disk_usage() {
local threshold="${1:-80}" # 默认阈值 80%
df -h | awk -v threshold="$threshold" '
NR>1 {
gsub(/%/, "", $5)
if ($5 > threshold) {
print "警告: " $1 " 使用率 " $5 "% 超过阈值 " threshold "%"
}
}'
}
# 查找大文件
find_large_files() {
local size="${1:-100M}" # 默认查找大于100M的文件
local dir="${2:-.}"
echo "查找大于 $size 的文件:"
find "$dir" -type f -size +"$size" -exec ls -lh {} \; 2>/dev/null | \
awk '{print $5, $9}' | sort -hr
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 网络和进程管理
# 端口检查
# 检查端口是否被占用
check_port() {
local port="$1"
local protocol="${2:-tcp}"
if command -v netstat >/dev/null 2>&1; then
netstat -tuln | grep ":$port "
elif command -v ss >/dev/null 2>&1; then
ss -tuln | grep ":$port "
else
echo "错误: 未找到 netstat 或 ss 命令" >&2
return 1
fi
}
# 检查端口并显示进程信息
check_port_with_process() {
local port="$1"
local pid=$(lsof -ti:$port 2>/dev/null)
if [ -n "$pid" ]; then
echo "端口 $port 被进程 $pid 占用:"
ps -p "$pid" -o pid,ppid,cmd
else
echo "端口 $port 未被占用"
fi
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 进程管理
# 查找并终止进程
kill_process_by_name() {
local process_name="$1"
local signal="${2:-TERM}"
local pids=$(pgrep "$process_name")
if [ -n "$pids" ]; then
echo "找到进程: $pids"
echo "$pids" | xargs kill -"$signal"
echo "已发送 $signal 信号"
else
echo "未找到进程: $process_name"
fi
}
# 监控进程资源使用
monitor_process() {
local process_name="$1"
local interval="${2:-5}"
while true; do
local pid=$(pgrep "$process_name" | head -1)
if [ -n "$pid" ]; then
echo "=== $(date) ==="
ps -p "$pid" -o pid,ppid,%cpu,%mem,cmd
echo
else
echo "进程 $process_name 未运行"
fi
sleep "$interval"
done
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 实用工具函数
# 日志记录
# 日志记录函数
log() {
local level="$1"
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $message" >&2
}
# 使用示例
log "INFO" "开始处理文件"
log "ERROR" "文件不存在"
log "WARN" "磁盘空间不足"
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 颜色输出
# 颜色输出函数
color_echo() {
local color="$1"
local message="$2"
case "$color" in
red) echo -e "\033[31m$message\033[0m" ;;
green) echo -e "\033[32m$message\033[0m" ;;
yellow) echo -e "\033[33m$message\033[0m" ;;
blue) echo -e "\033[34m$message\033[0m" ;;
purple) echo -e "\033[35m$message\033[0m" ;;
cyan) echo -e "\033[36m$message\033[0m" ;;
*) echo "$message" ;;
esac
}
# 使用示例
color_echo "green" "成功完成"
color_echo "red" "发生错误"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 进度条显示
# 简单进度条
show_progress() {
local current="$1"
local total="$2"
local width="${3:-50}"
local percentage=$((current * 100 / total))
local filled=$((current * width / total))
local empty=$((width - filled))
printf "\r["
printf "%*s" "$filled" | tr ' ' '='
printf "%*s" "$empty" | tr ' ' ' '
printf "] %d%%" "$percentage"
}
# 使用示例
for i in {1..100}; do
show_progress "$i" 100
sleep 0.1
done
echo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 数据处理
# CSV 文件处理
# 读取 CSV 文件
read_csv() {
local file="$1"
local delimiter="${2:-,}"
while IFS="$delimiter" read -r -a fields; do
echo "字段数量: ${#fields[@]}"
for i in "${!fields[@]}"; do
echo "字段 $((i+1)): ${fields[i]}"
done
echo "---"
done < "$file"
}
# 提取 CSV 特定列
extract_csv_column() {
local file="$1"
local column="$2"
local delimiter="${3:-,}"
cut -d"$delimiter" -f"$column" "$file"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 文本搜索和替换
# 批量文本替换
batch_replace() {
local search="$1"
local replace="$2"
local file_pattern="$3"
local directory="${4:-.}"
find "$directory" -name "$file_pattern" -type f | while read -r file; do
if grep -q "$search" "$file"; then
sed -i.bak "s/$search/$replace/g" "$file"
echo "已处理: $file"
fi
done
}
# 使用示例
batch_replace "old_text" "new_text" "*.txt" "/path/to/files"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 最佳实践
# 脚本头部模板
#!/usr/bin/env bash
# 脚本描述
# 作者: Your Name
# 日期: $(date +%Y-%m-%d)
set -euo pipefail # 严格模式
IFS=$'\n\t' # 安全的IFS设置
# 脚本配置
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "$0")"
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 错误处理模板
# 错误处理函数
error_exit() {
echo "错误: $1" >&2
exit 1
}
# 检查命令是否存在
check_command() {
if ! command -v "$1" >/dev/null 2>&1; then
error_exit "命令 '$1' 未找到,请先安装"
fi
}
# 检查文件是否存在
check_file() {
if [ ! -f "$1" ]; then
error_exit "文件 '$1' 不存在"
fi
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 使用说明
- 复制代码片段:根据需要复制相应的函数到你的脚本中
- 修改参数:根据实际情况调整函数参数和默认值
- 测试验证:在测试环境中验证代码片段的正确性
- 错误处理:添加适当的错误处理和日志记录
# 注意事项
- 所有函数都使用
local声明局部变量 - 使用
set -euo pipefail启用严格模式 - 错误信息输出到
stderr(>&2) - 函数参数使用默认值语法
${param:-default} - 使用
command -v检查命令是否存在
通过这个代码片段集合,你可以快速构建高效的 Shell 脚本,提高日常开发效率! 🚀
上次更新: 2025/10/18, 12:58:23