shell脚本入门

文章目录

shell 复制代码
bash test.sh
source test.sh
./test.sh

变量

用户自定义变量

shell 复制代码
COUNT=1
echo $COUNT
Z=hello
echo $Z
unset Z
echo $Z

特殊变量

只读变量

  • 变量值不允许修改(重新赋值)的情况
  • 无法使用 unset删除
  • readonly

位置变量和预定义变量

  • $0 与键入的命令行一样,脚本文件名

  • 1,2,......9 {10} 分别包含第一个到第十个命令行参数

  • $# 命令行参数的个数

  • @ 命令行所有参数:"1,2,......9"

    • 每个参数可独立处理,适合逐个遍历
  • \* 命令行所有参数,:"1,2,......9"

    • 是一个整体,通常用于拼接
  • $? 前一个命令的执行状态,执行成功,返回0,否则返回非0

  • 当前进程的pid进程号

  • $USER 表示用户名称

  • $HOME 表示用户的宿主目录

  • $PWD 表示当前所在工作目录

  • $PATH 表示可执行用户程序的默认路径

语句

说明性语句

  • 以#号开始到该行结束,不被解释执行注释行可以出现在程序中的任何位置,既可以单独占用一行, 也可以接在执行语句的后面
  • 以#号开始到所在行的行尾部分,都不被解释执行

功能性语句

read命令

  • 功能:从标准输入(键盘)或文件描述符读取用户输入,并将值赋给变量
  • 语法:read [选项] [变量名1 变量名2 ...]
  • 常用选项:
    • -p 显示提示信息 <font style="color:rgb(51,51,51);">read -p "请输入用户名:" username</font>
    • -t 设置输入超时时间 <font style="color:rgb(51,51,51);">read -t 5 -p "输入倒计时:"</font>
    • -s 静默模式,隐藏内容,如输入密码 read -s -p "密码:" password

算数运算

expr命令
  • sum=$(expr 5 + 3)
  • sum=expr 5 + 3``
  • C=$(( (A+B)*2))
  • C=expr ( A + B ) * 2``

需要用命令置换符``时,乘法需要转义,特别注意空格问题

$((......))展开命令
  • echo $(( (5 + 3) * 2 ))
  • 乘法无需转义,支持逻辑运算
  • C=$(( ( A + B ) * 2))
  • 变量名可以不加 $ 符号直接使用
let 命令
  • let a=5 + 3 # a=8
  • 变量可以直接使用,特别注意空格细节

test命令

写法
  • test 表达式
    • 标准写法,推荐
  • 表达式

    • 方括号写法(需注意表达式与方括号间的空格)
数值比较
  • -eq 等于则为真 test $num1 -eq $num2
  • -ne 不等于则为真 [ $a -ne $b ]
  • -gt 大于则为真 test 10 -gt 5
  • -ge 大于等于则为真 [ $count -ge 100 ]
  • -ge 大于等于则为真 [ $count -ge 100 ]
  • -le 小于等于则为真 [ $score -le 60 ]
字符串测试
  • = / == 字符串相等则为真 <font style="color:rgb(51,51,51);">test "$str1" = "$str2"</font>
  • != 字符串不等则为真 <font style="color:rgb(51,51,51);">[ "$var" != "exit" ]</font>
  • -z 字符串长度为0则为真 <font style="color:rgb(51,51,51);">test -z "$input"</font>
  • -n 字符串长度非0则为真 <font style="color:rgb(51,51,51);">[ -n "$username" ]</font>
文件测试
  • -e 文件存在则为真 test -e /path/to/file
  • -f 是普通文件则为真 [ -f "data.txt" ]
  • -d 是目录则为真 test -d /home/user
  • -r 文件可读则为真 [ -r config.ini ]
  • -w 文件可写则为真 test -w log.txt
  • -x 文件可执行则为真 [ -x script.sh ]
  • -s 文件存在且非空则为真 test -s output.log
逻辑运算
  • -a 逻辑与(AND) test -e file.txt -a -r file.txt
  • -o 逻辑或(OR) [ $age -gt 18 -o "$role" = "admin" ]
  • ! 逻辑非(NOT) test ! -d /invalid_path

[[ $num -gt 10 && "$str" != "error" ]] #bash中推荐&&、||

控制语句

分支语句

单分支
  • 语法
shell 复制代码
if [ 条件判断 ]; then
  # 条件成立时执行的代码
fi
  • 示例
shell 复制代码
#!/bin/bash
A=3
B=3
if test $A -eq $B ;then
  echo "A=B"
fi
if [ $A -eq $B ];then
  echo "A=B"
fi
双分支
  • 语法
shell 复制代码
if [ 条件判断 ]; then
  # 条件成立时执行
else
  # 条件不成立时执行
fi
  • 示例
shell 复制代码
#!/bin/bash
if [[ -e "file" && -f "file" ]]
then
  echo "yes"
else
  touch file
fi
多路分支
  • 语法
shell 复制代码
if [ 条件1 ]; then
  # 条件1成立时执行
elif [ 条件2 ]; then
  # 条件2成立时执行
else
  # 所有条件均不成立时执行
fi
  • 示例
shell 复制代码
#!/bin/bash
# 脚本生成一个 100 以内的随机数,提示用户猜数字,根据用户的输入,提示用户猜对了,猜小了或猜大了
# 使用取余算法将随机数变为 1‐100 的随机数
num=$((RANDOM%100+1))
echo "$num"
# 使用 read 提示用户猜数字
read -p "计算机生成了一个 1‐100 的随机数,你猜: " number
if [ $number -eq $num ]
then
  echo "恭喜,猜对了"
elif [ $number -gt $num ]
then
  echo "Oops,猜大了"
else
  echo "Oops,猜小了"
fi
多路分支case
  • 语法
bash 复制代码
case 变量 in
  模式1)
    命令1
    ;;
  模式2|模式3) # 支持逻辑或`|`匹配多个模式
    命令2
    ;;
  *) # 默认分支(匹配其他所有情况)
    默认命令
    ;;
esac
  • 示例
shell 复制代码
#!/bin/bash
file="A_9"
case $file in
  *.jpg|*.png)
    echo "图像文件" ;;
  *.txt|*.md)
    echo "文本文件" ;;
  [A-Za-z]_[0-9])
    echo "字母+下划线+数字格式" ;;
  *)
    echo "未知类型" ;;
esac

循环语句

for

  • 语法
shell 复制代码
for 变量 in 元素1 元素2 ... 元素N
do
  # 执行命令(使用 $变量)
done
  • 示例
shell 复制代码
for file in `ls`
do
	echo "文件:$file"
done

while语句

  • 语法
shell 复制代码
while [ 条件 ]
do
  # 执行的命令
done
  • 示例
shell 复制代码
#!/bin/bash

while [ "$input" != "exit" ]
do
	read -p "input your text(exit will quit) " input
	echo "your input:$input"
done

循环控制语句

  • break :跳出整个循环
  • continue :跳过当前迭代,进入下一次循环
shell 复制代码
count=1
while [ $count -lt 5 ]
do
	if [ $count == 2 ]
	then
		#break
		count=`expr $count + 1`
		continue
	fi
	echo "$count"
	count=`expr $count + 1`
done
相关推荐
Shanxun Liao9 小时前
Cenots 7.9 配置多台 SSH 互信登陆免密码
linux·运维·ssh
j_xxx404_9 小时前
Linux:第一个程序--进度条|区分回车与换行|行缓冲区|进度条代码两个版本|代码测试与优化
linux·运维·服务器
looking_for__10 小时前
【Linux】Ext系列文件系统
linux
OliverH-yishuihan11 小时前
开发linux项目-在 Windows 上 基于“适用于 Linux 的 Windows 子系统(WSL)”
linux·c++·windows
南棱笑笑生12 小时前
20251224给飞凌OK3588-C开发板适配Rockchip原厂的Buildroot【linux-6.1】系统时确认ssh服务【内置dropbear】
linux·c语言·ssh·rockchip
I · T · LUCKYBOOM12 小时前
30.Firewalld-Linux
linux·运维·安全
沙滩小绵羊12 小时前
Linux常见命令
linux·运维·服务器
驰羽13 小时前
NAT模式下VMware的虚拟机DNS解析失败的问题解决
linux·网络·dns
菜鸡000113 小时前
安装G2O
linux
誰能久伴不乏14 小时前
epoll 学习踩坑:`fcntl` 设置非阻塞到底用 `F_SETFL` 还是 `F_SETFD`?
linux·服务器·网络·c++·tcp/ip