shell脚本

前言

本文主要参考Shell 教程 | 菜鸟教程


Shell 基础知识点


一、变量

  1. 定义与命名规则

    your_name="runoob"  # 正确
    your_name = "runoob"  # 错误(等号两侧不能有空格)
    
    • 命名规则:字母/数字/下划线,不以数字开头,避免关键字。
    • 常量习惯大写:MAX=100
  2. 使用变量

    echo $your_name    # 直接引用
    echo ${your_name}  # 明确变量边界(推荐)
    
    • 重新赋值:your_name="new_value"(无需$)。
  3. 只读变量与删除

    readonly PI=3.14
    unset PI  # 错误(只读变量无法删除)
    unset temp_var  # 删除普通变量
    

二、字符串操作

  1. 引号区别

    str1='Hello, $USER'  # 原样输出,不解析变量
    str2="Hello, $USER"  # 解析变量和转义符
    
  2. 拼接与长度

    name="Alice"
    greeting="Hello, "$name"!"  # 拼接
    echo ${#name}  # 输出5(长度)
    
  3. 子字符串与查找

    str="abcdef"
    echo ${str:1:3}       # 输出bcd(从索引1截取3字符)
    echo `expr index "$str" cd`  # 输出3(查找字符位置)
    

三、数组

  1. 定义与访问

    arr=("A" "B" "C")        # 索引数组
    echo ${arr[1]}           # 输出B
    declare -A assoc_arr     # 关联数组
    assoc_arr["key"]="value"
    
  2. 数组操作

    echo ${arr[@]}       # 输出所有元素
    echo ${#arr[@]}      # 数组长度
    echo ${!assoc_arr[@]} # 输出所有键
    

四、参数传递

  1. 特殊变量

    $0  # 脚本名
    $1  # 第一个参数
    $#  # 参数个数
    $*  # 所有参数(合并为一个字符串)
    $@  # 所有参数(保持独立)
    $$  # 当前进程ID
    $?  # 上条命令退出状态
    
  2. 示例

    ./script.sh arg1 arg2
    echo "第一个参数: $1"  # arg1
    

五、运算符

  1. 算术运算

    val=`expr 2 + 2`      # 需空格和反引号
    val=$((2 + 2))        # 更简洁的方式
    
  2. 关系与逻辑运算

    [ $a -eq $b ]   # 等于
    [[ $a < 10 && $b > 5 ]]  # 逻辑与
    
  3. 字符串比较

    [ "str1" = "str2" ]   # 相等性检查
    [ -z "$str" ]         # 是否为空
    
  4. 文件测试

    [ -f "file.txt" ]    # 是否为普通文件
    [ -x "/bin/bash" ]   # 是否可执行
    
  5. 自增/自减

    let count++          # 自增
    count=$((count - 1)) # 自减
    

六、注释与多行处理

  1. 单行注释

    # 这是一个注释
    
  2. 多行注释

    :<<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

六、常见问题与解决

  1. 变量未解析
    确保使用双引号包裹变量:echo "$var",避免空格引发的问题。

  2. 权限问题
    脚本需可执行权限:chmod +x script.sh

  3. 换行符错误
    如果脚本在 Windows 编写,换行符需转换为 Unix 格式:dos2unix script.sh

  4. 特殊字符转义
    使用反斜杠或单引号处理特殊字符:

    echo "Quote: \"Hello\""   # 输出:Quote: "Hello"
    echo 'Price: $100'        # 输出:Price: $100(变量不解析)
    
  5. 函数返回值限制
    使用 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”的行。

posted @ 2025-03-11 15:42  玉米面手雷王  阅读(22)  评论(0)    收藏  举报