【Linux】shell脚本二

2、接收用户的参数

shell脚本已经内设了用于接收用户输入参数的变量,变量之间可以使用空格隔开。

如:./test.sh one two three four

  • $0:对应的是当前shell脚本程序的名称,即test.sh
  • $#:对应的是总共有几个参数,此条命令总共有4个参数
  • $*:对应的是所有位置的参数值,分别是one two three four
  • $?:对应的是显示上一次命令的执行返回值
  • $1:对应的是第1个参数,即one
  • $2:对应的是第2个参数,即two

3、条件表达式

shell脚本中的条件测试语句可以判断表达式是否成立,若条件成立则返回数字0,否则便返回其它随机数值。

如:[ cd /home/ln ],注意条件表达式的两边都必须要有一个空格

文件测试语句

它是使用指定条件来判断文件是否存在或权限是否满足等情况的运算符。

bash 复制代码
# 判断/home/ln是否为一个目录类型的文件

[ -d /home/ln ]
echo $? # 如果返回值是0,则目录存在;如果返回值为非零值,则目录不存在

|----|---------------|
| -d | 测试文件是否为目录类型 |
| -e | 测试文件是否存在 |
| -f | 判断是否为一般文件 |
| -r | 测试当前用户是否有权限读取 |
| -w | 测试当前用户是否有权限写入 |
| -x | 测试当前用户是否有权限执行 |
[文件测试语句的相关参数]

逻辑测试语句

用于对测试结果进行逻辑分析,根据测试结果实现不同的效果。

逻辑"与":&&。表示当前面的命令执行成功后才会执行它后面的命令。

bash 复制代码
# 先判断/home/ln是否存在,若存在则输出Exist
[ -e /home/ln ] && echo "Exist"

**逻辑"或":|| 。**表示当前面的命令执行失败后才会执行它后面的命令。

bash 复制代码
# 先判断当前登录的用户是否是root管理员身份,若是,则不执行后面的命令;若不是,则执行后面的命令。
[ $USER = root ] || echo "user"

**逻辑"非":! 。**表示把条件测试中的结果取相反值。

bash 复制代码
# 先判断当前登录用户是否是root用户,如果是,取反后,变为不是,则执行后面的语句
[ !$USER = root ] || echo "administrator"

由于当前登录的账号是root账号,那么第一个条件取反后为假,则不会执行 echo "user"语句,就会执行echo "root"语句。

bash 复制代码
# 当前登录的账号为root账号
[ !$USER = root ] && echo "user" || echo "root" #输出root

整数值比较语句

整数比较运算符仅是对数字的操作,不能将数字与字符串、文件等内容一起操作。

如:[ 10 -gt 10 ]

|---------|----------------------|
| -eq | equal,是否等于 |
| -ne | not equal,是否不等于 |
| -gt | greater than,是否大于 |
| -lt | less than,是否小于 |
| -le | less equal,是否等于小于 |
| -ge | greater equal,是否大于等于 |
[整数比较运算符]

字符串比较语句

用于判断测试字符串是否为空值,或两个字符串是否相同。经常用来判断某个变量是否未被定义(即内容为空值)。

bash 复制代码
# 当前语系的环境变量值LANG不是英语(en.US).
[ $LANG != "en.US" ] && echo "Not en.US" # 执行结果:Not en.US

|--------|-------------|
| = | 比较字符串内容是否相同 |
| != | 比较字符串内容是否不同 |
| -z | 判断字符串内容是否为空 |
[字符串比较运算符]

4、流程控制语句

if条件语句

**单分支结构:**由if、then、fi关键词组成。

bash 复制代码
#!/bin/bash
DIR="/home/LN"
if [ ! -e $DIR ] # 判断该目录是否存在,如果不存在则创建
  then mkdir -p $DIR
fi

**双分支结构:**由if、then、else、fi关键词组成。

如下所示,编写一个ping.sh 脚本,执行语句:bash ping.sh 192.168.1.101。

/dev/null:

是一个被称作Linux黑洞的文件,把输出信息重定向到这个文件等同于删除数据(类似于没有回收功能的垃圾箱),可以让用户的屏幕窗口保持简洁。

bash 复制代码
#!/bin/bash
#-c是规定尝试ping的次数为3次;-i表示每个数据包发送间隔为0.2s;-W表示等待的超时时间为3s
ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
if [ $? -eq 0 ] # $?显示上一次命令的执行返回值,如果上一条命令 成功执行,则返回0,否则,返回非0
  then
  echo "Host $1 is on-line."
else
  echo "Host $1 is off-line."
fi

**多分支结构:**由if、then、else、elif、fi关键词组成

如下所示例子,编写score.sh脚本:read用来读取用户输入信息的命令,它能够把接收到的用户输入信息赋值给后面的指定变量;-p参数用来向用户显示一定的提示信息。

bash 复制代码
#!/bin/bash
read -p "Enter your score(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]
  then echo "$GRADE is excellent!!"
elif [$GRADE -ge 70 ] && [ $GRADE -le 84 ]
  then echo "$GRADE is good!"
else
  echo "$GRADE is fail!"
fi

for循环语句

如下所示例子,先创建一个user.txt文档,里面有多个用户名,然后编写脚本。

bash 复制代码
#!/bin/bash
read -p "Enter the users password:" PASSWORD
for UNAME in `cat users.txt`
do
  id $UNAME &> /dev/null
  if [ $? -eq 0 ]
    then echo "Username already exists."
  else
    userad $UNAME &> /dev/null
    echo "$PASSWORD" | password --stdin $UNAME &> /dev/null
  
  if [ $? -eq 0 ]
    then echo "$UNAME, creat successfully."
  else
    echo "$UNAME, create fail."
  fi
  
  fi
done

while循环语句

适用于在执行前不确定最终执行的次数。

如下例子所示,编写一个GuessNumber.sh脚本

bash 复制代码
#!/bin/bash

NUMBER=$(expr $RANDOM % 1000) # 随机生成一个0-32767的随机数,然后对1000进行取余操作
TIMES=0
echo "数值的范围在0-999之间,猜猜看?"

while true
do
  read -p "请输入你猜测的数字:" INT
  let TIMES++
  if [ $INT -eq $NUMBER ]
  then
    echo "恭喜你,猜对了。你一共猜了 $TIMES 次。"
    exit 0
  elif [ $INT -gt $NUMBER ]
  then
    echo "你猜得太高了。"
  else
    echo "你猜得太低了。"
  fi
done

case条件语句

case语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;而如果数据不在所列出的范围内,则会去执行星号(*)中所定义的默认命令。

如下所示例子,编写CheckKey.sh脚本。

bash 复制代码
#!/bin/bash
read -p "请输入一个字符,并按Enter键确认:" KEY

case "$KEY" in
[a-z] | [A-Z])
echo "你输入的是字母。"
;;
[0-9])
echo "您输入的是数字。"
;;
*)
echo "您输入的是空格、功能键或其他字符。"
esac

5、计划任务

一次性计划任务

只执行一次,用于满足临时的工作需求,默认采用的是交互式 方法。可以用 at 命令实现,格式:at 时间 **,**如下所示:

bash 复制代码
# 今晚23:00重启网站服务
at 23:00
at > systemctl restart httpd
at > #这里同时按下Ctrl+D来结束编写计划任务

可以通过管道符实现非交互式的方法创建一次性计划任务。

bash 复制代码
echo "systemctl restart httpd" | at 23:00

如果想要查看已设置好但还未执行的一次性计划任务,可以使用 at -l 命令;

如果想要将其删除,可以使用 atrm 任务序号

长期性计划任务

如果想要能够周期性地、有规律地执行某些具体的任务,那么Linux系统默认启用的crond服务是最佳选择。

  • **crontab -e:**创建、编辑计划任务
  • **crontab -l:**查看当前计划任务
  • **crontab -r:**删除某条计划任务
  • **crontab -u:**以管理员身份登录系统后,编辑他人的计划任务。

使用crond服务设置任务的参数格式:分钟、小时、日、月、星期 命令 。如果有些字段没有设置,则需要使用**星号(*)**占位。

|--------|-----------------------|
| 分钟 | 0~59的任意整数 |
| 小时 | 0~23的任意整数 |
| | 1~31的任意整数 |
| | 1~12的任意整数 |
| 星期 | 0~7的任意整数。其中0和7均表示星期日 |
| 命令 | 要执行的命令或程序脚本 |
[使用crond设置任务的参数字段说明]

计划任务中的"分"必须要有数值,绝对不能为空或是*;

而"日"和"星期"字段不能同时使用,否则就会发生冲突。

如下例子所示:

bash 复制代码
crontab -e
crontab -l
0 2 * * 1,3,5 /home/LN/tar -czvf backup.tar.gz /home/ln #所以命令(tar)需要用绝对路径来写

除了可以使用逗号(,) 来分别表示多个时间段,如"8,9,11"表示8月、9月、11月,还可以使用减号(-) 来表示一段连续的时间周期,如字段"日"的取值为"11-15",表示每月的11~15日;使用**除号(/)**表示执行任务的间隔时间,如"*/2"表示每隔2分钟执行一次任务。

相关推荐
岚天start9 分钟前
解决方案—K8S集群的日志按天并按照命名空间分类定时同步到日志服务器
服务器·docker·kubernetes·shell·日志备份
佐杰32 分钟前
什么是DevOps
运维·devops
CaracalTiger32 分钟前
本地部署 Stable Diffusion3.5!cpolar让远程访问很简单!
java·linux·运维·开发语言·python·微信·stable diffusion
ai_xiaogui33 分钟前
AIStarter跨平台完工:Win/Mac/Linux一键部署Stable Diffusion
linux·macos·stable diffusion·aistarter·kritaai·跨平台部署
顾安r1 小时前
11.10 脚本算法 五子棋 「重要」
服务器·前端·javascript·游戏·flask
梁萌1 小时前
linux中使用docker安装MySQL
linux·运维·docker·容器·mysql安装
文言一心1 小时前
SenseVoice 离线部署指南(Xinference Docker v1.12)
运维·docker·ai·容器
AIchiNiurou1 小时前
mermaid install for free docker
运维·docker·容器
wei_shuo1 小时前
智能运维×低资源占用:金仓数据库助力能源企业降本增效与国产化替换实践
运维·数据库·king base
❀͜͡傀儡师1 小时前
根据docker服务保存日志脚本,时间可选版本
运维·docker·容器