#!/bin/bash
# 这是一个注释
echo "Hello, World!"
#!/bin/bash
称为 shebang,指定解释器#
开头chmod +x script.sh
)name="Linux"
echo "Hello, $name" # 变量引用
readonly PI=3.14 # 只读变量
unset name # 删除变量
变量 | 含义 |
---|---|
$0 |
脚本名称 |
$1-$9 |
脚本参数 |
$# |
参数个数 |
$* |
所有参数 |
$@ |
所有参数(可迭代) |
$? |
上条命令退出状态 |
$$ |
当前进程PID |
str="Hello World"
# 长度
echo ${#str} # 11
# 子串
echo ${str:0:5} # Hello
echo ${str:6} # World
# 替换
echo ${str/World/Linux} # Hello Linux
# 大小写转换
echo ${str^^} # HELLO WORLD
echo ${str,,} # hello world
# 定义数组
arr=("a" "b" "c")
# 访问元素
echo ${arr[1]} # b
# 所有元素
echo ${arr[@]}
# 数组长度
echo ${#arr[@]}
# 关联数组(需要bash 4+)
declare -A map
map["key1"]="value1"
map["key2"]="value2"
echo ${map["key1"]}
# 如果var未设置,则使用default
${var:-default}
# 如果var未设置或为空,则使用default
${var-default}
# 如果var未设置,则设置var为default并返回
${var:=default}
# 检查变量是否设置,未设置则报错
${var:?error message}
if [[ -e "file.txt" ]]; then
echo "文件存在"
fi
常用文件测试操作符:
操作符 | 含义 |
---|---|
-e |
文件存在 |
-f |
是普通文件 |
-d |
是目录 |
-s |
文件大小不为0 |
-r |
可读 |
-w |
可写 |
-x |
可执行 |
-L |
是符号链接 |
-nt |
比另一个文件新 |
-ot |
比另一个文件旧 |
if [[ "$str1" == "$str2" ]]; then
echo "字符串相等"
fi
if [[ "$str1" > "$str2" ]]; then
echo "str1在字典序中大于str2"
fi
if [[ -z "$str" ]]; then
echo "字符串为空"
fi
if [[ -n "$str" ]]; then
echo "字符串非空"
fi
if (( a > b )); then
echo "a大于b"
fi
数值比较操作符:-eq
, -ne
, -gt
, -ge
, -lt
, -le
if [[ condition1 && condition2 ]]; then
# AND 操作
fi
if [[ condition1 || condition2 ]]; then
# OR 操作
fi
if [[ ! condition ]]; then
# NOT 操作
fi
# 传统形式
for i in {1..5}; do
echo $i
done
# C语言风格
for ((i=0; i<5; i++)); do
echo $i
done
# 遍历数组
arr=("a" "b" "c")
for item in "${arr[@]}"; do
echo $item
done
# 遍历文件
for file in *.txt; do
echo "Processing $file"
done
# while循环
count=0
while [[ $count -lt 5 ]]; do
echo $count
((count++))
done
# until循环(条件为假时执行)
count=0
until [[ $count -ge 5 ]]; do
echo $count
((count++))
done
# 读取文件行
while IFS= read -r line; do
echo "$line"
done < "file.txt"
# break
for i in {1..10}; do
if [[ $i -eq 5 ]]; then
break
fi
echo $i
done
# continue
for i in {1..5}; do
if [[ $i -eq 3 ]]; then
continue
fi
echo $i
done
function greet() {
local name=$1 # 局部变量
echo "Hello, $name"
return 0
}
greet "Alice"
echo "返回值: $?"
function sum() {
local total=0
for num in "$@"; do
((total+=num))
done
echo $total
}
result=$(sum 1 2 3 4 5)
echo "总和: $result"
return
返回状态码 (0-255)echo
或 printf
输出结果,通过命令替换捕获function get_date() {
date +%F
}
today=$(get_date)
echo "今天是: $today"
#!/bin/bash
# -x 打印执行的命令
# -e 命令失败时立即退出
# -u 使用未定义变量时报错
set -euxo pipefail
function debug() {
echo "DEBUG: $*" >&2
}
debug "这是一个调试信息"
function cleanup() {
echo "清理临时文件..."
rm -f /tmp/tempfile*
}
trap cleanup EXIT INT TERM
function log() {
local level=$1
local message=$2
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
}
log "INFO" "脚本开始执行"
# config.cfg
# key=value
# name=Alice
declare -A config
while IFS='=' read -r key value; do
config["$key"]="$value"
done < "config.cfg"
echo "Name: ${config[name]}"
function progress_bar() {
local width=50
local percent=$1
local filled=$((width * percent / 100))
local empty=$((width - filled))
printf "["
printf "%${filled}s" | tr ' ' '#'
printf "%${empty}s" | tr ' ' ' '
printf "] %d%%\r" "$percent"
}
for i in {0..100..5}; do
progress_bar $i
sleep 0.1
done
echo
set -euo pipefail
[[ ]]
代替 [ ]
进行条件测试$(...)
代替反引号进行命令替换在下一篇文章中,我们将深入探讨进程控制、信号处理和并行执行等更高级的主题。