Shell脚本基础编程

注意:

  1. 赋值规则 :等号 = 前后无空格name=John ✔️,name = John ❌);
  2. 引号规则
    • 双引号 ":保留变量值(echo "name=$name"name=John);
    • 单引号 ':原样输出(echo 'name=$name'name=$name);

一、变量规格(基本变量)

  1. 直接定义

    • 语法:变量名="值"(等号两侧无空格
    • 示例:name="john"
    • 说明:Shell 默认变量为字符串类型
  2. 只读变量

    • 关键字:readonly
    • 语法:readonly 变量名=值变量名=值; readonly 变量名
    • 特点:赋值后不可修改、不可删除
  3. 删除变量

    • 关键字:unset
    • 语法:unset 变量名
    • 注意:只读变量无法被 unset 删除

二、变量类型

1. 整数变量

  • 声明关键字:declare -i
  • 作用:强制变量为整数类型,支持直接算术运算
bash 复制代码
declare -i num=9
num=num+1
echo "值为:$num" #值为:10

2. 数组变量(基本数据 / 普通数组)

  • 定义语法:数组名=(值1 值2 值3 ...)
  • 特点:使用数字下标(从 0 开始)访问元素
bash 复制代码
arr=(aasdasd b c)
echo ${arr[0]}  # 取第1个值:a
echo ${arr[@]}  # 取所有值:a b c
echo ${!arr[@]} # 取所有下标:0 1 2
echo ${#arr[@]} # 取长度:3
echo ${#arr[0]} #获取数组指定元素的长度:7

3. 关联数组(键值关联)

  • 声明关键字:declare -A
  • 作用:使用字符串键(key) 索引值(value),实现键值对存储
bash 复制代码
declare -A user_info
user_info["name"]="John"
user_info["age"]=30
user_info["city"]="New York"

# 1. ${!user_info[@]} → 获取所有键
echo "所有键:${!user_info[@]}"  # 输出:所有键:name age city

# 2. ${user_info[@]} → 获取所有值(无!)
echo "所有值:${user_info[@]}"  # 输出:所有值:John 30 New York

4、环境变量

export 变量名=值全局生效,子进程可继承配置系统环境(如 PATH)

5、只读变量

readonly 变量名 / declare -r赋值后不可修改 / 删除固定配置(如版本号)

6、特殊变量

变量 核心含义 示例场景 示例输出 / 说明
$0 当前执行的脚本名(含路径 / 纯文件名) 执行 ./test.sh $0 = ./test.sh(或 test.sh
$1-$9 命令行传入的第 1~9 个参数 执行 ./test.sh 10 20 30 $1=10$2=20$3=30
${10} 第 10+ 个参数(需加花括号) 执行 ./test.sh 1 2 ... 10 ${10}=10(直接写 $10 会识别为 $1+0
$# 命令行传入的参数总个数 执行 ./test.sh 10 20 $#=2
$? 上一条命令的退出状态码(0 = 成功,非 0 = 失败) 执行 ls && echo $? 执行 ls xxx && echo $? 0(ls 成功)2(ls 失败)
$$ 当前脚本的 PID(进程号) 任意脚本中执行 echo $$ 输出一串数字(如 12345),唯一标识当前脚本进程
$* 所有参数(视为一个整体) 执行 ./test.sh a b c "$*" = "a b c"
$@ 所有参数(视为独立个体) 执行 ./test.sh a b c "$@" = "a" "b" "c"

三、基本运算符

  • 算数运算符

    • 一般使用expr,但注意,表达式和运算符之间要有空格隔开,且整个式子必须用反引号包含起来(esc键下方)
    bash 复制代码
    a=1
    b=2
    num=`expr $a \* $b` #+、-、/、%、=用法一致,但*需要添加\,转义
    echo $num # 2
    
    #==判断两数是否相等
    if [ $a == $b ]
    then echo "a 等于 b"
    fi
    
    #判断两个数是否不相等
    if [ $a != $b ]
    then echo "a 等于 b"
    fi
  • 关系运算符
    *

    运算符 说明 举例
    -eq 检测两个数是否相等,相等返回 true。 [ a -eq b ] 返回 false。
    -ne 检测两个数是否不相等,不相等返回 true。 [ a -ne b ] 返回 true。
    -gt 检测左边的数是否大于右边的,如果是,则返回 true。> [ a -gt b ] 返回 false。
    -lt 检测左边的数是否小于右边的,如果是,则返回 true。< [ a -lt b ] 返回 true。
  • 布尔运算符
    *

    运算符 说明 举例
    ! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
    -o 或运算,有一个表达式为 true 则返回 true。 [ a -lt 20 -o b -gt 100 ] 返回 true。
    -a 与运算,两个表达式都为 true 才返回 true。 [ a -lt 20 -a b -gt 100 ] 返回 false。
    运算符 说明 举例
    && 逻辑的 AND [[ a -lt 100 \&\& b -gt 100 ]] 返回 false
    || 逻辑的 OR [[ a -lt 100 || b -gt 100 ]] 返回 true
  • 字符串运算符
    *

    运算符 说明 举例
    = 检测两个字符串是否相等,相等返回 true。 [ a = b ] 返回 false。
    != 检测两个字符串是否不相等,不相等返回 true。 [ a != b ] 返回 true。
    -z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
    -n 检测字符串长度是否不为 0,不为 0 返回 true。 [ -n "$a" ] 返回 true。
    $ 检测字符串是否不为空,不为空返回 true。 [ $a ] 返回 true。
    bash 复制代码
    获取长度:${#str}
    str="hello"
    echo ${#str}  # 输出 5
    
    字符串截取:${str:起始位置:长度}
    str="hello"
    echo ${str:1:3}  # 输出 ell
    
    字符串替换:${str/旧字符串/新字符串}
    str="hello"
    echo ${str/ll/xx}  # 输出 hexxo
  • 文件测试运算符(按使用频率排序)
    *

    运算符 核心含义 示例(判断成立则返回 true)
    -f 检测是否为普通文件(非目录 / 设备) [ -f /etc/passwd ](passwd 是普通文件)
    -d 检测是否为目录 [ -d /tmp ](tmp 是目录)
    -e 检测文件 / 目录是否存在(通用) [ -e /root ](root 目录存在)
    -r 检测当前用户是否有读权限 [ -r /etc/shadow ](普通用户无读权限)
    -w 检测当前用户是否有写权限 [ -w /tmp/test.txt ](tmp 下文件可写)
    -x 检测当前用户是否有执行权限 [ -x /bin/ls ](ls 命令有执行权限)
    -s 检测文件是否非空(大小 > 0) [ -s /var/log/messages ](日志文件非空)
    -L 检测是否为符号链接(软链接) [ -L /etc/rc.local ](rc.local 是软链接)
    -b 检测是否为块设备文件(磁盘 / 分区) [ -b /dev/sda ](sda 是块设备)
    -c 检测是否为字符设备文件(终端 / 串口) [ -c /dev/tty1 ](tty1 是字符设备)
    -S 检测是否为套接字文件(socket) [ -S /var/run/mysqld/mysqld.sock ]
    -nt 检测文件 A是否比文件 B 新(修改时间) [ fileA -nt fileB ]
    -ot 检测文件 A是否比文件 B 旧(修改时间) [ fileA -ot fileB ]
    -ef 检测两个文件是否为同一个文件(硬链接 / 相同 inode) [ file1 -ef file2 ]

四、输出

1、echo

2、printf(可以多试试,这个挺有趣的)

bash 复制代码
printf "%d %o %x\n" 52 52 52 #十进制、八进制、十六进制
printf "%f %e\n" 2.43 2.444543534#浮点数、科学计数发
printf "%s\n" "john"#字符串
printf "%c\n" "aaa"#字符,只会输出a
相关推荐
虾..1 小时前
Linux 基于TCP实现服务端客户端通信(守护进程版)
linux·运维·服务器
勇闯逆流河1 小时前
【Linux】Linux基础开发工具(git、dbg)
linux·运维·服务器·开发语言·c++·git
我爱学习好爱好爱1 小时前
ELK日志分析平台(五):Filebeat 部署与 Nginx 日志采集(输出至 Logstash)(基于Rocky Linux 9.6)
linux·nginx·elk
returnthem1 小时前
Docker数据卷
运维·docker·容器
繁华如雪亦如歌1 小时前
Linux:进程间通信
linux
芥子沫2 小时前
Memos捷径(Shortcuts)用法介绍
linux·服务器·windows
mengchanmian2 小时前
docker 国内云服务器开源镜像
运维·docker·容器
糟糕喔2 小时前
k8s运维-configmap和secret(4)
运维·容器·kubernetes
数据知道2 小时前
MongoDB自动化运维脚本:详细讲述日常维护任务批量化处理的实用技巧
运维·mongodb·自动化