shell脚本
前言
本文主要参考Shell 教程 | 菜鸟教程
Shell 基础知识点
一、变量
- 
定义与命名规则 your_name="runoob" # 正确 your_name = "runoob" # 错误(等号两侧不能有空格)- 命名规则:字母/数字/下划线,不以数字开头,避免关键字。
- 常量习惯大写:MAX=100。
 
- 
使用变量 echo $your_name # 直接引用 echo ${your_name} # 明确变量边界(推荐)- 重新赋值:your_name="new_value"(无需$)。
 
- 重新赋值:
- 
只读变量与删除 readonly PI=3.14 unset PI # 错误(只读变量无法删除) unset temp_var # 删除普通变量
二、字符串操作
- 
引号区别 str1='Hello, $USER' # 原样输出,不解析变量 str2="Hello, $USER" # 解析变量和转义符
- 
拼接与长度 name="Alice" greeting="Hello, "$name"!" # 拼接 echo ${#name} # 输出5(长度)
- 
子字符串与查找 str="abcdef" echo ${str:1:3} # 输出bcd(从索引1截取3字符) echo `expr index "$str" cd` # 输出3(查找字符位置)
三、数组
- 
定义与访问 arr=("A" "B" "C") # 索引数组 echo ${arr[1]} # 输出B declare -A assoc_arr # 关联数组 assoc_arr["key"]="value"
- 
数组操作 echo ${arr[@]} # 输出所有元素 echo ${#arr[@]} # 数组长度 echo ${!assoc_arr[@]} # 输出所有键
四、参数传递
- 
特殊变量 $0 # 脚本名 $1 # 第一个参数 $# # 参数个数 $* # 所有参数(合并为一个字符串) $@ # 所有参数(保持独立) $$ # 当前进程ID $? # 上条命令退出状态
- 
示例 ./script.sh arg1 arg2 echo "第一个参数: $1" # arg1
五、运算符
- 
算术运算 val=`expr 2 + 2` # 需空格和反引号 val=$((2 + 2)) # 更简洁的方式
- 
关系与逻辑运算 [ $a -eq $b ] # 等于 [[ $a < 10 && $b > 5 ]] # 逻辑与
- 
字符串比较 [ "str1" = "str2" ] # 相等性检查 [ -z "$str" ] # 是否为空
- 
文件测试 [ -f "file.txt" ] # 是否为普通文件 [ -x "/bin/bash" ] # 是否可执行
- 
自增/自减 let count++ # 自增 count=$((count - 1)) # 自减
六、注释与多行处理
- 
单行注释 # 这是一个注释
- 
多行注释 :<<COMMENT 多行注释内容 COMMENT
关键注意事项
- 变量赋值:等号两侧无空格,如 var=value。
- 字符串引号:双引号解析变量,单引号保持原样。
- 数组下标:索引从0开始,关联数组需 declare -A。
- 参数引用:$*和$@在双引号中的区别(合并 vs 独立)。
- 运算符空格:[ $a == $b ]方括号内必须留空格。
Shell基础知识点2
一、echo vs printf 的区别
| 特性 | echo | printf | 
|---|---|---|
| 自动换行 | 默认自动换行 | 需手动添加 \n换行 | 
| 格式化输出 | 不支持复杂格式 | 支持类似 C 语言的格式符(%s, %d) | 
| 多参数处理 | 空格分隔参数,自动拼接 | 需严格匹配格式字符串和参数数量 | 
| 转义字符 | 需 -e参数启用转义 | 默认支持转义字符 | 
| 示例: | 
echo "Hello\tWorld"        # 输出:Hello\tWorld
echo -e "Hello\tWorld"     # 输出:Hello   World
printf "Hello\tWorld\n"    # 输出:Hello   World(自动换行)
二、test 命令的常见用法
用于条件判断,支持数值、字符串、文件测试。
数值比较
[ $a -eq $b ]   # 等于
[ $a -ne $b ]   # 不等于
[ $a -gt $b ]   # 大于
字符串比较
[ "$str1" = "$str2" ]   # 相等
[ -z "$str" ]           # 字符串为空
[ -n "$str" ]           # 字符串非空
文件测试
[ -e file ]    # 文件存在
[ -d dir ]     # 是目录
[ -x file ]    # 文件可执行
注意:
- 方括号 [ ]内必须留空格:[ $a -eq 10 ]。
- 字符串比较建议用双引号包裹变量,避免空值错误:[ "$str" = "hello" ]。
三、流程控制结构
1. if-else
if [ condition ]; then
    commands
elif [ condition ]; then
    commands
else
    commands
fi
示例:
if [ $num -gt 10 ]; then
    echo "大于10"
else
    echo "小于等于10"
fi
2. for 循环
for var in list; do
    commands
done
示例:
for i in {1..5}; do
    echo "Number: $i"
done
3. while 循环
while [ condition ]; do
    commands
done
示例:读取文件内容
while read line; do
    echo "Line: $line"
done < file.txt
4. case 语句
case $var in
    pattern1)
        commands ;;
    pattern2)
        commands ;;
    *)
        default ;;
esac
示例:
case $OS in
    "Linux")
        echo "使用Linux" ;;
    "Windows")
        echo "使用Windows" ;;
    *)
        echo "未知系统" ;;
esac
四、函数与返回值
定义与调用
function greet() {
    echo "Hello, $1"
}
greet "Alice"  # 输出:Hello, Alice
返回值处理
- 
return返回整数(0-255),通过$?获取。
- 
echo返回字符串或任意值,通过$(函数)捕获。
 示例:避免返回值溢出add() { local sum=$(($1 + $2)) echo $sum # 正确方式:输出结果 } result=$(add 300 200) echo "Sum: $result" # 输出:Sum: 500
五、输入/输出重定向
常用操作
| 命令 | 说明 | 
|---|---|
| command > file | 将输出重定向到 file。 | 
| command < file | 将输入重定向到 file。 | 
| command >> file | 将输出以追加的方式重定向到 file。 | 
| n > file | 将文件描述符为 n 的文件重定向到 file。 | 
| n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 | 
| n >& m | 将输出文件 m 和 n 合并。 | 
| n <& m | 将输入文件 m 和 n 合并。 | 
| << tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 | 
# 将输出和错误写入日志
ls /nonexistent > output.log 2>&1
# 快速清空文件
> file.log
Here Document
cat << EOF
This is a multi-line
text block.
EOF
六、常见问题与解决
- 
变量未解析 
 确保使用双引号包裹变量:echo "$var",避免空格引发的问题。
- 
权限问题 
 脚本需可执行权限:chmod +x script.sh。
- 
换行符错误 
 如果脚本在 Windows 编写,换行符需转换为 Unix 格式:dos2unix script.sh。
- 
特殊字符转义 
 使用反斜杠或单引号处理特殊字符:echo "Quote: \"Hello\"" # 输出:Quote: "Hello" echo 'Price: $100' # 输出:Price: $100(变量不解析)
- 
函数返回值限制 
 使用echo代替return返回大数或字符串。
七、查找文件
管道符(|)
管道符允许你将一个命令的输出作为另一个命令的输入。它的基本形式是在两个命令之间放置一个竖线字符(|)。例如,如果你想要查找某个目录下所有包含特定文本的文件,你可以先用find命令找到那些文件,然后通过管道符将其输出传递给grep命令进行进一步过滤。
grep
grep是一个强大的文本搜索工具,它可以在文件内容中查找符合正则表达式模式的所有行,并显示出来。最简单的使用方式是直接跟上要搜索的文本或模式,如grep "search_term" filename.txt。结合管道符使用时,grep可以用来过滤前一个命令的输出。
find
find命令用于在目录层次结构中查找文件。它可以根据文件名、类型、大小、修改时间等多种条件进行搜索。基本语法为find [path] [expression],其中[path]是你希望开始搜索的目录,而[expression]则是指定搜索条件的部分。
结合使用示例
假设你想在一个项目目录及其子目录中找到所有包含“error”一词的.log文件,你可以这样操作:
find . -name "*.log" | xargs grep "error"
这里,find . -name "*.log"会找出当前目录及所有子目录下的.log文件,xargs会读取前面find命令的输出并构造一个新的命令行传递给grep,于是grep "error"会在这些文件中查找包含“error”的行。
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号