【Linux---08】Shell脚本

文章目录

  • 1. 前置说明
    • 1.1 创建shell脚本
    • 1.2 执行shell脚本
    • 1.3 调试shell脚本
    • 1.4 字符冲突
  • 2. 变量
    • 2.1 创建&使用变量
    • 2.2 位置变量
    • 2.3 引号规则
  • 3. 数组
    • 3.1 创建数组
    • 3.2 使用数组
  • 4. 运算符
    • 4.1 比较&数值运算
      • 4.1.1 方式一:[ ]
      • 4.1.3 方式二:(()) 📌
    • 4.2 逻辑运算
    • 4.3 文件运算
  • 5. 控制语句
    • 5.1 分支语句
      • 5.1.1 if分支
      • 5.1.2 模式匹配
    • 5.2 循环语句
      • 5.2.1 for循环
      • 5.2.2 while循环
  • 6. 函数定义
    • 6.1 没有返回值的函数
    • 6.2 有返回值的函数
  • 7. exit与return
  • 8. 连接数据库
    • 8.1 连接MySQL数据库

1. 前置说明

shell脚本是linux系统中的一个可执行文件,它可以用来批量执行linux命令,比手动输入大量命令要高。

1.1 创建shell脚本

创建shell脚本有几个必须点:

  1. 文件必须以.sh结尾

  2. 文件的开头必须加上#! /biin/bash,指明脚本解释器

    cd ~
    vim myshell.sh
    

    在这里插入图片描述

1.2 执行shell脚本

shell脚本的执行:

  1. 方式一:使用sh命令

    sh myshell.sh
    
  2. 方式二:授予文件可执行权限,这样可以直接输入文件名运行文件

    # chmod a+x myshell.sh
    chmod +x myshell.sh   # 为当前用户增加对该文件权限
    myshell.sh
    

    在这里插入图片描述

  3. 方式三:使用source命令

    source myshell.sh
    

    shsource执行的区别:source一个脚本时,脚本中的所有命令都会在当前Shell中执行,这意味着脚本可以修改当前Shell环境的变量或行为。这与sh是不同的,sh脚本不能修改其父Shell的环境。

  4. 方式四:使用bash命令

    bash myshell.sh
    

    bash 是 sh 的超集

1.3 调试shell脚本

在执行脚本前面加上-x

  1. sh -x myshell.sh (未授权)
  2. -x myshell.sh (已授权)
    在这里插入图片描述

1.4 字符冲突

通过下面可以知道$字符可以用来获取变量值,但是当我们要打印$符号怎么办?
使用\转义。其他字符冲突也是这样处理。

#! /bin/bash
money=100
echo "我有\$${money}元"  # 输出:我有$100元

2. 变量

2.1 创建&使用变量

  1. 创建变量:和Java一样,=左边是变量名,右边是变量值。

    注意事项:

    1. 变量名首字符必须为字母,名字只能用字母、数字、下滑线,不要用bash关键字。非法的名字:8var、var-8
    2. 变量名=值,等号两边不能有空格。
    3. 值只有字符串类型,值可以用单引号、可以用双引号,也可以都不用。但是值中有空格或特殊字符必须需要用双引号或单引号引起来。
    #! /bin/bash
    name="zhansgan"
    age=18
    echo $name  # 输出:zhangsan
    echo "${name}目前${age}岁!"  # 输出:zhangsan目前18岁!
    
  2. 使用变量:$变量名${变量名} 形式获取变量值。一般首先使用$变量名,当存在歧义没有达到理想效果时使用${变量名}方式,获取数组值必须用后者。

2.2 位置变量

如果要想向shell脚本里传入参数,可以在运行shell脚本时携带参数。在shell脚本内可以通过一些符号获取传递的值:

  1. $0:脚本的名称

  2. $1:脚本的第一个参数,$2是第二个参数,以此类推

  3. $#:传入脚本的参数个数

  4. $*:传入的所有参数拼接为一个字符串后返回

    #! /bin/bash
    # 判断当前目录下的所有文件,哪些是文件,哪些不是文件 
    arr=(`ls ./`)
    for file in ${arr[*]}
    doif [ -f file ];thenecho "$file is a file"elseecho "$file is not a file"if
    dome
    
  5. $@:传入的每个参数是一个字符串

  6. $?:上一条命令执行是否成功,0表示执行成功,非0表示执行失败

    $(命令)可以获取命令的执行结果
    在这里插入图片描述

  7. $$:当前进程的id

比如:有 a.sh 脚本,内容如下

#! /bin/bashecho $0
echo $1
echo $2
echo $#
echo $*
echo $@
echo $?

在这里插入图片描述

2.3 引号规则

  1. 单引号:里面的所有字符都是普通字符,不能够获取变量值。
  2. 双引号:会保留变量特性。可以使用$变量名获取变量值。
    #! /bin/bash
    name="zhansan"
    echo '$name'   # 输出:$name
    echo "$name"   # 输出:zhangsan
    
  3. 倒引号:引起来的命令将会被执行,执行后的结果作为这个表达式的值
    在这里插入图片描述

3. 数组

3.1 创建数组

  1. 方式一:直接定义并初始化。
    #! /bin/bash
    arr=("aaa" "bbb" "ccc")
    

    注意:元素间使用空格,而不是逗号分隔;并且后续可以继续添加元素,并不是静态的。

  2. 方式二:使用declare -a
    #! /bin/bash
    # 1. 定义并初始化
    declare -a arr=("aaa" "bbb" "ccc")# 2. 先定义,再赋值
    declare -a arr
    arr[0]="aaa"
    arr[1]="bbb"
    arr[2]="ccc"
    

3.2 使用数组

  1. 获取数组长度:${#数组名[@|*]} eg:${#arr[*]}

  2. 读取数组元素

    1. 读取一个元素:${数组名[下标]}
    2. 一次读取所有元素:${数组名[*]}
  3. 给数组元素赋值:数组名[下标]=值

  4. 删除数组元素:unset 数组名[下标]

    [root@localhost shell]# arr1=("a1" "b1" "c1")
    [root@localhost shell]# echo ${arr1[*]}
    a1 b1 c1
    [root@localhost shell]# declare -a arr2=("a2" "b2" "c2")
    [root@localhost shell]# echo ${arr2[*]}
    a2 b2 c2
    [root@localhost shell]# declare -a arr3
    [root@localhost shell]# arr3[0]="a3"
    [root@localhost shell]# arr3[1]="b3"
    [root@localhost shell]# arr3[2]="c3"
    [root@localhost shell]# echo ${arr3[*]}
    a3 b3 c3
    [root@localhost shell]# 
    # 查看数组长度
    [root@localhost shell]# echo ${#arr3[*]}
    3
    # 获取数组第一个元素
    [root@localhost shell]# echo ${arr3[0]}
    a3
    # 删除数组第一个元素,数组长度-1
    [root@localhost shell]# unset arr3[0]
    [root@localhost shell]# echo ${#arr3[*]}
    2
    [root@localhost shell]# echo ${arr3[*]}
    b3 c3
    

4. 运算符

4.1 比较&数值运算

4.1.1 方式一:[ ]

  1. 语法:[ 比较&运算表达式 ] 注意:整体前后空格,运算符前后空格
  2. 支持的运算有
    1. 比较运算(数值比较)
      在这里插入图片描述
    2. 比较运算(字符串比较)
      在这里插入图片描述
  3. 例子:
    1. 比较运算(数值比较)的例子:
      [root@localhost shell]# [ 1 -eq 1 ] && echo 'ok'
      ok
      [root@localhost shell]# [ 1 -lt 0 ] && echo 'ok'   
      [root@localhost shell]# [ 1 -lt 2 ] && echo 'ok' 
      ok
      # 没有空格隔开,报错
      [root@localhost shell]# [ 1 -lt 2] && echo 'ok' 
      -bash: [: 缺少 ]
      # 变量替换也可以
      [root@localhost shell]# a=1
      [root@localhost shell]# [ $a -lt 2 ] && echo 'ok' 
      ok
      [root@localhost shell]# 
      
    2. 比较运算(字符串比较)的例子:
      [root@localhost shell]# [ "aaa" == "aaa" ] && echo 'ok'
      ok
      [root@localhost shell]# 
      [root@localhost shell]# [ "aaa" != "bbb" ] && echo 'ok'    
      ok
      # 字符串判空
      [root@localhost shell]# s=aaa
      # 字符串非空
      [root@localhost shell]# [ "${s}x" == "x" ] && echo 'ok'         
      [root@localhost shell]# 
      # 字符串为空
      [root@localhost shell]# s=""
      [root@localhost shell]# [ "${s}x" == "x" ] && echo 'ok'
      ok
      

4.1.3 方式二:(()) 📌

  1. 语法:((比较&运算表达式)) 注意:整体前后不需要空格,运算符前后空格
  2. 支持的运算有
    1. 比较:==!=<<=
    2. 数值运算:加减乘除取模自加【a++或++a】、+=
  3. 加上$可取运算后的值$((数值运算))
  4. 例子:
    #! /bin/bash
    a=10
    b=20
    echo "$((a+b))"  # 输出:30a=10
    echo "$((a%2))"  # 删除:0a=10
    echo "$((a++))"  # 输出:10,此时a=11a=10
    echo "$((++a))"  # 输出:11,此时a=11a=10
    echo "$((a!=2))"  # 输出:11,此时a=11a=10
    echo "$((a==2))"  # 输出:11,此时a=11a=10
    echo "$((a<=2))"  # 输出:0a=10
    echo "$((a<2))"  # 输出:0a=10
    echo "$((a+=2))"  # 输出:12
    

4.2 逻辑运算

  1. 语法:

    1. 采用[ ]进行运算
      在这里插入图片描述

    2. 采用(())进行运算

      运算符说明示例
      !非运算((! 2 < 1)) && echo ‘ok’
      |或运算((1 == 1 | 1 == 2)) && echo ‘ok’
      &与运算((1 == 1 & 1 == 2)) && echo ‘ok’
      &&短路与((1 == 1 && 1 == 2)) && echo ‘ok’
      ||短路或((1 == 1|| 1 == 2)) && echo ‘ok’
  2. 细节:&&有一个非常有用的作用—将多行命令变成一行,这对于平台化的shell脚本执行非常有帮助。通过平台执行shell脚本时,往往限制只能执行一行命令。比如:cd bin && sh run.sh $@
    在这里插入图片描述

4.3 文件运算

语法:[ 运算符 文件相对路径|绝对路径 ] 注意:整体前后空格,运算符前后空格
在这里插入图片描述

[root@localhost shell]# [ -e hello.sh ] && echo 'ok'        
ok
[root@localhost shell]# [ -f hello.sh ] && echo 'ok'
ok
[root@localhost shell]# [ -d hello.sh ] && echo 'ok'      
[root@localhost shell]# 

5. 控制语句

5.1 分支语句

5.1.1 if分支

# 方式一:表达式后面写分号,再写then
if  条件表达式一 ; then   表达式一true时执行这里
elif  条件判断式二 ; then    表达式二true时执行这里
elif  条件判断式三 ; then    表达式三true时执行这里
else    都不成立时,执行这里
fi# 方式二:表达式后面写不写分号,则必须换行后写thenthen
if  条件表达式一 then 表达式一true时执行这里
elif  条件判断式二 then 表达式二true时执行这里
elif  条件判断式三then 表达式三true时执行这里
else    都不成立时,执行这里
fi

注意 :

  1. 最后要以 if反过来的fi结尾
  2. 关键字ifelif 后面必须接空格,否则报错。

例子:

[root@localhost shell]# vim test.sh
#! /bin/bash
cmd=$1
if [ $cmd == "start" ]then echo "start"
elif [ $cmd == "stop" ]then echo "stop"
elif [ $cmd == "restart" ]then echo "restart"
elseecho "other"
fi
[root@localhost shell]# sh test.sh 123   # 输出:other

5.1.2 模式匹配

case $var in模式1)  代码块1;; 模式2)    代码块2    ;;    模式3)    代码块3   ;;    *)    代码块4    ;;
esac

注意 :最后要以 case反过来的esac结尾

例子:

[root@localhost shell]# vim s6.sh 
#! /bin/bash
cmd=$1
case $cmd in"start") echo "start operation";;"stop") echo "stop operation";;"restart") echo "restart operation";;*) echo "other operation";;
esac

5.2 循环语句

5.2.1 for循环

  1. 语法:
    # 方式一:for-each循环
    for 循环变量 in 数据列表
    do循环体代码段
    done# 方式二:下标循环
    for ((控制变量的初始化;循环的条件;循环控制变量的更新))
    do循环体代码段
    done
    
    1. 数据列表{1..100}:表示1到100
      #! /bin/bash
      for i in {1..10}
      doecho $i
      done
      # 打印1到10
      
    2. 结尾必须写上done
    3. 关键字for 后面可以不接空格,但是推荐空格。
  2. 例子:
    ① for-each循环
    #! /bin/bash
    # 判断当前目录下哪些文件是普通文件
    arr=(`ls ./`)
    # 遍历数组的每个元素(文档)
    for f in ${arr[*]}
    do# 判断是否是文件if [ -f $f ]; thenecho "$f is file"fi
    done
    
    ② 下标循环
    #! /bin/bash
    # 计算1-10内的偶数之和
    sum=0
    for((i=1;i<=10;i++))
    doif [ $((i%2)) -eq 0 ];thensum=$((sum+i))fi
    done
    echo "sum=${sum}"
    

5.2.2 while循环

  1. 语法:

    while ((循环的条件))
    do循环体代码段
    done
    
    1. done结束
    2. 关键字for 后面可以不接空格,但是推荐空格。
  2. 例子

    #! /bin/bash
    i=1
    while((i<10))
    do((i++))
    done
    echo "i=$i"  # 输出:i=10
    

6. 函数定义

6.1 没有返回值的函数

#!/bin/bashfun(){echo "hello student!"
}fun   # 输入方法名时,调用函数

6.2 有返回值的函数

#!/bin/bashnum1=$1
num2=$2
funandReturn(){return $(($num1+$num2))
}funandReturn  # 输入函数名,会调用函数
echo "输入的两个数字之和为 $? !" # 通过 $? 获取函数返回值

7. exit与return

  1. 位置不同:exit可以在脚本的任何地方;而return在shell脚本的函数内或者最后一行。
  2. 作用不用:exit用于结束当前进程;return在函数内时用于结束函数,在shell脚本的最后一行时用于返回脚本中最后一个命令的 exit status
  3. 细节:当return位于shell脚本的最后一行时,用sh执行会报错,得用source执行。
    在这里插入图片描述

8. 连接数据库

8.1 连接MySQL数据库

# 1. 设置主机信息、账号密码、数据库名
MYSQL_CLIENT=$HOME/.jumbo/bin/mysql  # mysql的安装路径/bin/mysql,如果此时机器MySQL已经配置了环境变量,则可以写 MYSQL_CLIENT=mysql
MYSQL_HOST="xxxx"
MYSQL_PORT="xxxx"
MYSQL_USER="xxxx"
MYSQL_PASSWORD="xxxx"
MYSQL_DATABASE="xxxx"# 2. 登入MySQL  
#   --skip-column-names:输出结果中不显示列名
#   -e:表示后续会接一个 SQL 查询语句,这个 SQL 查询语句会被 MySQL 客户端执行
LOGIN_MYSQL="${MYSQL_CLIENT} -h${PALO_HOST} -P${PALO_PORT} -u${PALO_USER} -p${PALO_PASSWORD} ${PALO_DATABASE} --skip-column-names -e"# 3. 执行sql
result=${LOGIN_MYSQL} "select * from table"

拉取数据时,如果需要保证数据已经加载完毕,可以采用拉取两次,进行对比的方式,以保证数据拉取完成:

event_day=`date -d "$BASETIME" +'%Y%m%d'`SQL="select count(1) from xxx where count_date=${event_day};"i=0
while (( i <= 50 ))
do((i++))# 拉取第一次count_1=$($MYSQL_LOGIN "${SQL}")echo "get _1 data done, count_1 = ${count_1}"sleep 5m# 拉取第二次count_2=$($MYSQL_LOGIN "${SQL}")echo "get _2 data done, count_2 = ${count_2}"sleep 5m# 两者对比if ((count_1 > 0 && count_2 > 0 && count_1==count_2));thenecho "month_dump_db_check.sh [query_data_count] date=${event_day} success"exit ${EXE_SUCCESS}fi
doneecho "month_dump_db_check.sh [query_data_count] date=${event_day} failed"
exit ${EXE_FAIL}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/395541.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MongoDB】1.MongoDB下载与安装

目录 一、下载 二、安装 三、安装MongoDB Compass 四、连接 一、下载 官网地址&#xff1a; https://www.mongodb.com/download-center/community 二、安装 详细的安装教程可参考&#xff1a; MongoDB安装&#xff08;超详细&#xff09;_安装mongodb-CSDN博客 注意事项1&…

赛盈分销亮相AI科技大会暨亚马逊新增长大会,与企业共话跨境品牌发展新机遇!

八月开端&#xff0c;由知无不言与xmars和钱老师课堂联合主办的2024年AI科技大会暨亚马逊新增长大会在深圳宝安顺利开展&#xff0c;为期2天的跨境峰会吸引了上千位优秀的卖家朋友前来感受一场盛夏大狂欢。在本次跨境峰会里&#xff0c;邀请了多位不同领域的先锋人物&#xff0…

Android 文件上传与下载

在实际开发涉及文件上传不会自己写上传代码&#xff0c;一般 会集成第三网络库来做图片上传&#xff0c;比如android-async-http&#xff0c;okhttp等&#xff0c;另外还有七牛也提供 了下载和上传的API。 1.项目用到的图片上传的关键方法&#xff1a; 这里用到一个第三方的库…

新华三H3CNE网络工程师认证—路由基础

我们的一个个网络其实是由不同的广播域构成的&#xff0c;而路由器的作用就是用来连接不同的广播域。那么不同广播域之间是如何通信的呢&#xff1f;比如有三个网段&#xff0c;1.0、2.0和3.0。网段1.0和网段2.0通信需要构造数据包&#xff0c;源是1.1&#xff0c;目标去往2.1。…

Java程序的执行过程:从编译到垃圾回收,一文读懂Java程序的生命周期

你是否曾经好奇过当你编写一段Java代码并运行它时&#xff0c;背后究竟发生了什么&#xff1f;Java程序的执行过程似乎神秘而复杂&#xff0c;但实际上&#xff0c;它遵循着一系列精心设计的步骤。本文将为你揭开Java程序执行的神秘面纱&#xff0c;带你深入了解从源代码到最终…

SpringBoot企业人事管理系统-附源码与配套论文

1.1引言 随着计算机技术的飞速发展&#xff0c;计算机在各种单位机构管理中应用的普及﹐管理信息系统的开发在强调管理、强调信息的现代社会中也显得越来越重要。因此,利用计算机高效率地完成人事管理的日常事务&#xff0c;是适应现代各种单位机构制度要求、推动各种单位机构…

SpringBoot统一功能处理——拦截器

目录 一、什么是拦截器&#xff1f; 二、拦截器使用 2.1 定义拦截器 2.2 注册配置拦截器 三、拦截器详解 3.1 拦截器的拦截路径配置 3.2 拦截器执行流程 一、什么是拦截器&#xff1f; 拦截器是Spring框架提供的核心功能之一, 主要用来拦截用户的请求, 在指定方法前后,…

【2024年精选】分享7款国内大学ai写论文推荐网站工具

在2024年&#xff0c;AI技术的飞速发展为学术研究和论文写作带来了革命性的变化。众多AI论文写作工具应运而生&#xff0c;帮助学生和研究人员提高写作效率&#xff0c;提升论文质量。其中&#xff0c;AIPaperPass作为一款备受瞩目的国内AI写论文推荐网站工具&#xff0c;以其独…

CentOS7.6 HAproxy-7层负载均衡集群——实施方案

目录 1、前期环境准备 1.准备4台主机 1. 设置主机名 2. 设置IP地址然后重启网卡 3. 关闭防火墙和selinux 4. 全部的服务器完成时间统一 二、配置haproxy(192.168.200.11)服务器 1. 安装haproxy 2. haproxy 配置中分成五部分内容 3. 配置HAproxy&#xff08;192.168.2…

Animate软件基本概念:缓动、绘图纸外观及图层

FlashASer&#xff1a;AdobeAnimate2021软件零基础入门教程https://zhuanlan.zhihu.com/p/633230084 FlashASer&#xff1a;实用的各种Adobe Animate软件教程https://zhuanlan.zhihu.com/p/675680471 FlashASer&#xff1a;Animate教程及作品源文件https://zhuanlan.zhihu.co…

05_ Electron 自定义菜单、主进程与渲染进程通信

Electron 自定义菜单、主进程与渲染进程通信 一、定义顶部菜单二、Electron 自定义右键菜单1、使用 electron/remote 模块实现 三、 Electron 主进程和渲染进程通信场景1&#xff1a;渲染进程给主进程发送异步消息场景2&#xff1a;渲染进程给主进程发送异步消息&#xff0c;主…

数据结构--单链

#include "link.h" plink get_head() { plink pmalloc(sizeof(Link)); if(pNULL) { printf("申情节点失败\n"); return NULL; } p->len0; p->nextNULL; return p; } void head_insert(plink L,int a) {…

推荐一个uniapp选择文件上传的插件

插件地址&#xff1a;文件选择、文件上传组件&#xff08;图片&#xff0c;视频&#xff0c;文件等&#xff09; - DCloud 插件市场 支持 H5 / App / 微信小程序

K8s问题案例分析

1.worker节点宕机&#xff0c;请说明一下pod的驱逐流程&#xff1a; k8s有一个节点控制器&#xff0c;节点控制器在一段时间内无法和kubelet通信&#xff0c;那么就会给节点打上unknown 状态&#xff0c;并自动创建NoExecute污点,避免调度器调度新的pod到该节点。同时已经在这…

基于目标检测的目标跟踪(python)

文章目录 概要环境准备目标检测实现目标跟踪实现整合后的代码可能遇到的问题Could not load library libcudnn_ops_infer.so.8. Error: libcudnn_ops_infer.so.8: cannot open shared object file: No such file or directory参考概要 基于目标检测的目标跟踪过程通常包括以下…

Python新手错误集锦(PyCharm)

# 自学Python&#xff0c;用Pycharm作环境。我这个手新到这时我学习的第一个编程软件&#xff0c;且本人专业是化学&#xff0c;以前对电脑最高级的使用是玩扫雷游戏。所以这里集合的错误都是小透明错误&#xff0c;大部分人请绕道。不断更新中...... 缩进错误 记住“indent”…

力扣面试经典算法150题:买卖股票的最佳时机

买卖股票的最佳时机 今天的题目是力扣面试经典150题中的数组的简单题: 多数元素 题目链接&#xff1a;https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/description/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述 给定一个数组 prices&#xf…

SX_错误声明定义了两个以上的数据类型BUG解决_14

具体报错&#xff1a; In file included from perfmon_priv.h:32,from perfmond.c:21: perfmon_api.h:7:18: 错误: 声明指定了两个以上的数据类型7 | #define uint8_t unsigned char perfmon_api.h:7:27: 错误: 声明指定了两个以上的数据类型7 | #define uint8_t unsigned cha…

大数据Flink(一百零六):什么是阿里云实时计算Flink版

文章目录 什么是阿里云实时计算Flink版 一、产品概述 二、产品架构 三、产品优势 什么是阿里云实时计算Flink版 阿里云实时计算Flink版是一套基于Apache Flink构建的⼀站式实时大数据分析平台&#xff0c;提供端到端亚秒级实时数据分析能力&#xff0c;并通过标准SQL降低业…

c++ - c++11(1)

文章目录 前言一、统一的列表初始化1、使用{ }初始化2、 std::initializer_list 二、声明1、auto2、decltype3、nullptr 三、范围for循环四、右值引用1、左值引用和右值引用2、左值引用和右值引用的比较3、左值引用的使用场景4、右值引用的使用场景5、完美转发 前言 一、统一的…