首页 > 系统相关 >Shell

Shell

时间:2023-07-21 15:46:26浏览次数:44  
标签:Shell lemon echo sh 033 root bash

shell 介绍

  • 什么shell
  • shell功能

一、什么是shell

shell是一个程序,采用C语言编写,是用户和linux内核沟通的桥梁。它既是一种命令语言,又是一种解释性的编程语言。通过一个图表来查看一下shell的作用。

作用:

kernel:为软件服务,接收用户或软件指令驱动硬件,完成工作

shell:命令解释器

user:用户接口,对接用户。

二、shell 功能

  • 命令行解释功能
  • 启动程序
  • 输入输出重定向
  • 管道连接
  • 文件名置换 (echo /*)
  • 变量维护
  • 环境控制
  • shell编程

shell 语法

  • 如何抒写一个shell脚本
  • shell脚本运行
  • shell中的特殊符号
  • 重定向
  • shell中数学运算

shell脚本就是一组命令的集合,按照先后顺序执行;自上而下写入到一个文本文件中,然后给予执行权限。

一、如何抒写一个shell脚本

  • shell脚本的命名

    • 名字要有意义,最好不要用a、b、c、d、1、2、3、4这种方式命名;虽然linux系统中,文件没有扩展名的概念,依然建议你用.sh结尾;名字不要太长,最好能在30个字节以内解决。例如:check_memory.sh
  • shell脚本格式

    • shell脚本开头必须指定脚本运行环境 以 #!这个特殊符号组合来组成。如: #!/bin/bash 指定该脚本是运行解析由/bin/bash来完成的;
shell脚本中,最好加入脚本说明字段
 #!/bin/bash
 #Author: lemon
 #Created Time: 2018/08/2712:27
 #Script Description: first shell study script
 #下面写执行的命令语句
 。。。
 。。。
 。。。

二、如何运行一个shell脚本

[root@lemon ~]# cat /etc/shells      #查看当前系统的所有shell环境
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash

脚本运行需要执行权限,当我们给一个文件赋予执行权限后,该脚本就可以运行。
[root@lemon ~]# chmod u+x filename

如果不希望赋予脚本执行权限,那么可以使用bash命令来运行未给予执行权限的脚本bash fiename
[root@lemon ~]# bash filename

三、shell中的特殊符号

~          家目录,cd ~ 代表进入用户家目录
!          执行历史命令,!! 执行上一条命令
$          变量中取内容符
+ - * / %  对应数学运算  加 减 乘 除 取余 
*          星号是shell中的通配符  匹配所有
?          问号是shell中的通配符  匹配除回车以外的一个字符
\          转义字符
``         反引号,命令中执行命令
' '        强转义,禁止引用其他变量值,$视为普通字符;意思就是' '号里面写的是什么,显示的就是什么
" "        弱转义,允许通过$符号引用其他变量值;意思就是将" "号里面变量名的变量值显示出来
|          管道符,把前边命令的输出结果,作为后边命令的处理对象
||         逻辑或,前边的命令执行成功,后面的不执行;前边的命令执行失败,后面的命令将会被执行
&          后台执行,仅在当前终端生效,断开终端后放在后台运行的进程也会随着退出
&&         逻辑与,只有前边的命令执行成功,才会执行后面的命令
;          和 && 符号不同的一点就是 他不管前面命令的结果是否成功,它都会执行后面命令

四、shell重定向

#默认是正确重定向 
        1>        重定向正确覆盖;把屏幕上的正确内容输出到文件 
	1>>       重定向正确追加;把屏幕上的正确内容以追加的形式输出到文件
	2>        重定向错误覆盖;把屏幕上的错误内容输出到文件
	2>>       重定向错误追加;把屏幕上的错误内容以追加的形式输出到文件
	&>        重定向混合覆盖;把屏幕上无论是正确还是错误的都输出到文件
	&>>       重定向混合追加;把屏幕上无论是正确还是错误以追加的形式都输出到文件

五、shell数学运算

#$双小圆括号运算,在shell中$(( ))也可以用来做数学运算(推荐)
[root@lemon ~]# echo $((100 + 3))
103
[root@lemon ~]# echo $((100 - 3)) 
97
[root@lemon ~]# echo $((100 * 3)) 
300
[root@lemon ~]# echo $((100 / 3)) 
33
[root@lemon ~]# echo $((100 % 3)) 
1
[root@lemon ~]# echo $((100 ** 3)) 
1000000

#expr 命令:只能做整数运算,格式比较古板,注意空格
[root@lemon ~]# expr 1 + 1
2
[root@lemon ~]# expr 5 - 2
3
[root@lemon ~]# expr 5 \* 2  #注意*出现应该转义,否则认为是通配符
10
[root@lemon ~]# expr 5 / 2
2


#使用bc计算器处理浮点运算,scale=2代表小数点保留两位
[root@lemon ~]# echo "scale=2; 100 + 3" | bc
103
[root@lemon ~]# echo "scale=2; 100 - 3" | bc
97
[root@lemon ~]# echo "scale=2; 100 * 3" | bc
300
[root@lemon ~]# echo "scale=2; 100 / 3" | bc
33.33

shell格式化输出

  • echo 命令
  • 颜色输出

一个程序需要有0个或以上输入,一个或更多输出

一、echo 命令介绍

  • 功能:将内容输出到默认显示设备

    • echo命令的功能是在显示器上显示一段文字,一般起到一个提示的作用。 功能说明:显示文字。
    • 补充说明:echo会将输入的字符串送往标准输出。输出的字符串间以空白字符隔开,并在 最后加上换行号。
  • 命令选项:

    • –help 显示帮助–version显示版本信息

    • -n 不要在最后自动换行

    • -e 若字符串中出现以下特殊字符,则特别加以处理,而不会将它当成一般文字输出:

      • \t 插入tab;
      • \n 换行且光标移至行首;
      • \a 发出警告声;
      • \c 忽略掉这个参数之后的任何字符信息;
        • \r 输出回车后的内容信息;
      • \v 换行但光标仍旧停留在原来的位置;与\f相同;
  • 举例说明:

# \n
[root@lemon ~]# echo -e "lemon\nhandsome"
lemon
handsome

# \t
[root@lemon ~]# echo -e "lemon\thandsome"
lemon	handsome

# \c
[root@lemon ~]# echo -e "lemon\chandsome"
lemon[root@lemon-min ~]# 

# \r
[root@lemon ~]# echo -e "lemo\rnhandsome"
nhandsome

# \v
[root@lemon ~]# echo -e "lemon\vhandsome"
lemon
     handsome

二、颜色代码

脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数 -e

示例如下:

下面是相应的字和背景颜色,可以自己来尝试找出不同颜色搭配
  echo -e "\033[31m 红色字 \033[0m"
  echo -e "\033[34m 黄色字 \033[0m"
  echo -e "\033[41;33m 红底黄字 \033[0m"
  echo -e "\033[41;37m 红底白字 \033[0m"
  
字颜色:30—–37
  echo -e "\033[30m 黑色字 \033[0m"
  echo -e "\033[31m 红色字 \033[0m"
  echo -e "\033[32m 绿色字 \033[0m"
  echo -e "\033[33m 黄色字 \033[0m"
  echo -e "\033[34m 蓝色字 \033[0m"
  echo -e "\033[35m 紫色字 \033[0m"
  echo -e "\033[36m 天蓝字 \033[0m"
  echo -e "\033[37m 白色字 \033[0m"
  
字背景颜色范围:40—–47
  echo -e "\033[40;37m 黑底白字 \033[0m"
  echo -e "\033[41;37m 红底白字 \033[0m"
  echo -e "\033[42;37m 绿底白字 \033[0m"
  echo -e "\033[43;37m 黄底白字 \033[0m"
  echo -e "\033[44;37m 蓝底白字 \033[0m"
  echo -e "\033[45;37m 紫底白字 \033[0m"
  echo -e "\033[46;37m 天蓝底白字 \033[0m"
  echo -e "\033[47;30m 白底黑字 \033[0m"
  
最后面控制选项说明
  \033[0m 关闭所有属性
  \033[1m 设置高亮度
  \033[4m 下划线
  \033[5m 闪烁
  \033[7m 反显
  \033[8m 消隐

设置前景色
  \033[40m — \33[47m 设置背景色
  \033[nA 光标上移n行
  \033[nB 光标下移n行
  \033[nC 光标右移n行
  \033[nD 光标左移n行
  \033[y;xH设置光标位置
  \033[2J 清屏
  \033[K 清除从光标到行尾的内容
  \33[s 保存光标位置
  \033[u 恢复光标位置
  \033[?25l 隐藏光标
  \033[?25h 显示光标

shell交互输入定义变量

一、read基本命令

  • 默认接受键盘的输入,回车符代表输入结束

  • read 命令选项:

    • -p 打印信息
    • -t 交互停留的时间
    • -s 隐藏在外面输入值的信息
    • -n 限制输入字符个数

二、read 基本示例

[root@lemon ~]# vim read.sh
#!/bin/bash
clear
echo "Centos linux 7 (Core)"
echo -e "Kernel `uname -r` an `uname -m`"
read -n 6 -p "login:" user
read -n 6 -t 10 -s -p "Passd:" passwd
echo
echo -e "login:$user\nPassd:$passwd"

# 执行此脚本
[root@lemon ~]# bash read.sh
Centos linux 7 (Core)
Kernel 3.10.0-693.el7.x86_64 an x86_64
login:lemon
Passd:
login:lemon
Passd:123123

变量

  • 变量介绍
  • 变量分类
  • 变量管理

一、变量介绍

在编程中,我们总有一些数据需要临时存放在内存,以待后续使用时快速读出。内存在系统启动的时候被按照1B一个单位划分为若干个块,然后统一编号(16进制编号),并对内存的使用情况做记录,保存在内存跟踪表中。
  • 那么问题来了,1G内存有多少个1B的单位呢?
计算机的单位:
1B=8bit
1KB=1024B
1MB=1024KB
1GB=1024MB
1TB=1024GB
1PB=1024TB
1EB=1024PB
1ZB=1024EB
...
好了,已经够大了!当然还有YB、BB更大的单位,同样进制也是1024.

1G=1024*1024*1024=1073741824B

假如你将一个1B的字符存入内存,如何读出呢?有没有一种大海捞针的感觉啊!我们讨论一下计算机是如何通过让我们快速将数据存在内存,如何从内存中读出数据的。我们研究过变量后就明白了。

  • 变量:变量是编程中最常用的一种临时在内存中存取数据的一种方式。

  • 变量存取原理

  • 从图片可以看出,当我们在脚本中定义变量存值的时候,可以从以下方面看到变化:

    • 内存占用:如果存的是一个字符则占用1个字节,如果存的是字符串则是字符串的长度加1个字节长度(\0是一个特殊字符,代表字符串结束)。

    • 变量名与内存空间关系:计算机中会将对应的内存空间和变量名称绑定在一起,此时代表这段内存空间已经被程序占用,其他程序不可复用;然后将变量名对应的值存在对应内存地址的空间里。

# 理解变量存储:STRING1="ABC"
1)0X5...0X8(物理地址) <===> STRING1(逻辑地址) <===> 存取数据(ABC)
         0x5...0x8是内存物理地址,是计算机寻址的依据;
         STRING1是给人看的,方便人记忆;

2)对于人来说STRING1上存的数据是ABC,对于计算机来说数据是存在物理地址上的;

3)在建立变量的时候计算机自动将逻辑地址(变量名)和物理地址做了对应。


#变量读出
1)当调用STRING1的时候,计算机会根据对应关系,找到物理地址

2)定位内存地址,读出数据并返回

二、变量分类

注意事项:一定要按顺序写位置变量名!比如:$1 $2 $3 $4 $5 $6,如果位置变量用到两位数或多位数的话就用{}括上;比如:echo '$10 是' ${10};如果不加就会出现问题!

  1. 本地变量:用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile、.bashrc文件中
  2. 全局变量:所有用户都可以使用,保存在/etc/profile、/etc/bashrc文件,可使用 export 命令查看系统变量
  3. 用户自定义变量:用户自定义,比如脚本中的变量
  4. 位置变量:可以放在任何位置的变量,$1、$2、$3……

案例解释

# 准备脚本
[root@lemon ~]# vim envd.sh
#!/bin/bash
echo '我是$1:' $1
echo '我是$2:' $2
echo '我是$3:' $3
echo '我是$4:' $4
echo '我是$5:' $5
echo '我是$6:' $6
echo '我是$7:' $7
echo '我是$8:' $8
echo '我是$9:' $9
echo '我是$10:' ${10}

# 执行此脚本
[root@lemon ~]# bash envd.sh q w e r t y u i o p
我是$1: q
我是$2: w
我是$3: e
我是$4: r
我是$5: t
我是$6: y
我是$7: u
我是$8: i
我是$9: o
我是$10: p
  1. 预定义变量:$0、$#、$*、$?
    • $?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错

    • $#:命令行中位置变量的个数

    • $0:当前执行的进程/程序名

    • $*:所有位置变量的内容,$@ 和 $*差不多。但是注意,他俩是有区别的!!!

      • 使用如下的脚本查看 $@ 和 $* 的区别
# 准备脚本
[root@lemon ~]# vim envd.sh
#!/bin/bash
echo "我是-->$1"
echo "我是-->$2"
echo "我是-->$3"
echo '=================================='
for i in "$*";do
        echo "$i"
done
echo '=================================='
for y in "$@";do
    echo "$y"
done
echo '=================================='

# 执行脚本
[root@lemon ~]# sh envd.sh a1 a2 a3
我是-->a1
我是-->a2
我是-->a3
==================================
a1 a2 a3
==================================
a1
a2
a3
==================================

案例解释:

# 准备脚本
[root@lemon ~]# vim envd.sh
#!/bin/bash
echo "我是-->$1"
echo "我是-->$2"
echo "我是-->$3"
echo "$?"
echo "$#"
echo "$*"
echo "$0"

# 执行脚本
[root@lemon ~]# bash envd.sh a1 a2 a3
我是-->a1
我是-->a2
我是-->a3
0
3
a1 a2 a3
envd.sh

三、使用变量

1. 定义变量

  • 变量格式: 变量名=值

  • 在shell编程中的变量名和等号之间不能有空格。

  • 变量名命名规则:

# 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
# 中间不能有空格,可以使用下划线(_)。
# 不能使用标点符号。
# 不能使用bash里的关键字(可用help命令查看保留关键字)。
  • 定义变量演示:
# 变量赋值,此种方法设置为本地变量
[root@lemon ~]# name='lemon'
[root@lemon ~]# pass='12345'

2. 读取变量内容

  • 读取方法:$变量名
# 变量内容读出
[root@lemon ~]# echo $name
lemon
[root@lemon ~]# echo $age
12345

3. 取消变量 unset

[root@lemon ~]# unset name
[root@lemon ~]# echo $name

4. 定义全局变量 export

[root@lemon ~]# export name='lemon'
  • 上述设置的变量其实都是一次性的变量,系统重启就会丢失。
  • 如果希望本地变量或者全局变量可以永久使用,可以将需要设置的变量写入变量文件中即可。

5. 定义永久变量

  • 本地变量:用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile、.bashrc文件中

  • 全局变量:所有用户都可以使用,保存在/etc/profile、/etc/bashrc文件中

# 本地变量
[root@lemon ~]# tail -1 .bash_profile
export name='lemon'
[root@lemon ~]# source .bash_profile

# 全局变量
[root@lemon ~]# tail -1 /etc/profile
export age=18
[root@lemon ~]# source /etc/profile

数组

  • 数组介绍
  • 基本数组
  • 关联数组
  • 案列分享

一、数组介绍

  • 概述:数组就是一组数据类型相同集合

  • 一个变量只能存一个值,但是现实中又很多值需要存储,那么变量就有些拘谨了。比如做一个学员信息表,一个班50个人,每个人6条信息,我们需要定义300个变量才能完成。恐怖恐怖,这只是一个班的学生,一个学校呢?一个市呢?......我想静静了!

  • 仔细想想上述的案例,一个学生六个信息:ID、姓名、性别、年龄、成绩、班级。可不可以定义六个变量就能存储这六类信息呢?答案是当然可以的!但变量不行,我们可以用数组。

二、基本数组

数组可以让用户一次赋予多个值,需要读取数据时只需通过索引调用就可以方便读出了。

1. 数组语法

数组名称=()                             #定义空元素的数组
数组名称=(元素1 元素2 元素3 ...)         #定义有元素的数组

2. 数组读出

${数组名称[索引]}
索引默认是元素在数组中的排队编号,默认第一个从0开始

3. 数组赋值

  • 数组赋值格式:数组名[下标]=值,下标不存在,则新增数组元素; 下标已有,则覆盖值。

方法1:一次赋一个值

[root@lemon ~]# array1[0]='tom'
[root@lemon ~]# array1[1]='jarry'

方法2:一次赋多个值

[root@lemon ~]# array2=(tom jack alice "bash shell")     #linux默认都是字符串类型数据
[root@lemon ~]# array3=(`cat /etc/passwd`)               #希望是将该文件中的每一个行作为一                                                          个元素赋值给数组array3

4. 查看基本数组-a

# 查看数组
[root@lemon ~]# declare -a

5. 访问数组元素

[root@lemon ~]# echo ${array1[0]}        #访问数组中的第一个元素
[root@lemon ~]# echo ${array1[*]}        #访问数组中所有元素  等同于 echo ${array1[@]}
[root@lemon ~]# echo ${#array1[*]}       #统计数组元素的个数
[root@lemon ~]# echo ${!array2[*]}       #获取数组元素中的所有索引
[root@lemon ~]# echo ${array1[*]:1}      #从数组下标1开始
[root@lemon ~]# echo ${array1[*]:1:2}    #从数组下标1开始,访问两个元素

6. 遍历数组

  • 默认数组通过数组元素的个数进行遍历
[root@lemon ~]# for i in `echo ${array1[*]}`;do echo $i; done
pear
apple
orange
peach

三、关联数组

1. 定义关联数组

  • 申明关联数组变量
[root@lemon ~]# declare -A ass_array1
[root@lemon ~]# declare -A ass_array2

2. 关联数组赋值

方法1:一次赋一个值

[root@lemon ~]# ass_array1[index1]=pear
[root@lemon ~]# ass_array1[index2]=apple
[root@lemon ~]# ass_array1[index3]=orange
[root@lemon ~]# ass_array1[index4]=peach

方法2:一次赋多个值

[root@lemon ~]# ass_array2=([index1]=tom [index2]=jack [index3]=alice [index4]='tool')

3. 查看关联数组-A

[root@lemon ~]# declare -A

4. 访问数组元素

@ 等同于 *

[root@lemon ~]# echo ${ass_array2[index2]}   #访问数组中的第二个元数 
[root@lemon ~]# echo ${ass_array2[*]}        #访问数组中所有元数  等同于 echo ${array1[@]}
[root@lemon ~]# echo ${#ass_array2[*]}       #获得数组元素的个数
[root@lemon ~]# echo ${!ass_array2[*]}       #获得数组元素的全部索引

5. 遍历数组

[root@lemon ~]# for i in `echo ${ass_array2[*]}`;do echo $i; done
tool
tom
jack
alice

6. 简单的学员信息系统

#!/bin/bash
for ((i=0;i<3;i++));do
      read -p "输入第$((i + 1))个人名: " name[$i]
      read -p "输入第$[$i + 1]个年龄: " age[$i]
      read -p "输入第`expr $i + 1`个性别: " gender[$i]
      echo
done

clear

echo -e "\t\t\t\t\t\t学员查询系统"

while true;do
      cp=0
      read -p "输入要查询的姓名: " xm
      [ $xm == "q" ] && exit
      for ((i=0;i<3;i++));do
          if [ "$xm" == "${name[$i]}" ];then
              echo -e "name: ${name[$i]}\nage: ${age[$i]}\ngender: ${gender[$i]}"
              cp=1
          fi
      done
      [ $cp -eq 0 ]&&echo "not found student"
done

shell流程控制-if判断语句

  • shell中的四大运算
  • if语法
  • 在写程序的时候,时常会对上一步执行是否成功如何判断苦恼,当我们今天学习了if就可以解决你的苦恼。
  • if语句在我们程序中就是用来做判断的,不管学习的是什么语言,以后只要涉及到判断的部分,都可以直接拿if来使用,不同的语言之间的if只是语法不同,原理是相同的。

一、shell中的运算

1. 数学比较运算

  • 示例:
-eq    #等于
[root@lemon ~]# [ 9 -eq 10 ] ; echo $?
1
[root@lemon ~]# [ 10 -eq 10 ] ; echo $?
0

-gt    #大于
[root@lemon ~]# [ 10 -gt 10 ] ; echo $?
1
[root@lemon ~]# [ 11 -gt 10 ] ; echo $?
0

-lt    #小于
[root@lemon ~]# [ 9 -lt 10 ] ; echo $?
0
[root@lemon ~]# [ 10 -lt 10 ] ; echo $?
1

-ge    #大于或等于
[root@lemon ~]# [ 9 -ge 10 ] ; echo $?
1
[root@lemon ~]# [ 11 -ge 10 ] ; echo $?
0
[root@lemon ~]# [ 10 -ge 10 ] ; echo $?
0

-le    #小于或等于
[root@lemon ~]# [ 9 -le 10 ] ; echo $?
0
[root@lemon ~]# [ 10 -le 10 ] ; echo $?
0
[root@lemon ~]# [ 11 -le 10 ] ; echo $?
1

-ne    #不等于
[root@lemon ~]# [ 9 -ne 10 ] ; echo $?
0
[root@lemon ~]# [ 10 -ne 10 ] ; echo $?
1
[root@lemon ~]# [ 11 -ne 10 ] ; echo $?
0

2. 字符串比较运算

  • 注意字符串,一定别忘了使用引号引起来

  • 示例:

==    #等于,也可以指写一个 = 号
[root@lemon ~]# [ 'lemon' == 'lemon' ] ; echo $?
0
[root@lemon ~]# [ 'lemon' == 'tom' ] ; echo $?
1

!=    #不等于
[root@lemon ~]# [ 'lemon' != 'lemon' ] ; echo $?
1
[root@lemon ~]# [ 'lemon' != 'tom' ] ; echo $?
0

-z    #检查字符串的长度是否为空,加上!号就是取反 ! -z
[root@lemon ~]# echo "$name"
lemon
[root@lemon ~]# echo "$named"

[root@lemon ~]# [ -z $name ] ; echo $?
1
[root@lemon ~]# [ -z $named ] ; echo $?
0
[root@lemon ~]# [ ! -z $name ] ; echo $?
0
[root@lemon ~]# [ ! -z $named ] ; echo $?
1

3. 文件比较与检查

  • 示例:
-e     #检查目录及文件是否存在
[root@lemon ~]# [ -e /etc ] ; echo $?
0
[root@lemon ~]# [ -e /etc/passwd ] ; echo $?
0
[root@lemon ~]# [ -e /etcc ] ; echo $?
1
[root@lemon ~]# [ -e /etcc/passwd ] ; echo $?
1

-d    #检查文件是否存在且为目录
[root@lemon ~]# [ -d /etc ] ; echo $?
0
[root@lemon ~]# [ -d /tom ] ; echo $?
1

-f    #检查文件是否存在且为文件
[root@lemon ~]# [ -f /etc/passwd ] ; echo $?
0
[root@lemon ~]# [ -f /etc/file ] ; echo $?
1

-nt    #检查file1是否比file2新,按照时间比对的
[root@lemon opt]# ll -h *
-rw-r--r-- 1 root root 0 6月   5 21:21 lemon.txt
-rw-r--r-- 1 root root 0 6月   5 21:28 tools.txt
[root@lemon opt]# [ lemon.txt -nt tools.txt ] ; echo $?
1
[root@lemon opt]# [ tools.txt -nt lemon.txt ] ; echo $?
0

-ot    #检查file1是否比file2旧,按照时间比对的
[root@lemon opt]# ll -h *
-rw-r--r-- 1 root root 0 6月   5 21:21 lemon.txt
-rw-r--r-- 1 root root 0 6月   5 21:28 tools.txt
[root@lemon opt]# [ lemon.txt -ot tools.txt ] ; echo $?
0
[root@lemon opt]# [ tools.txt -ot lemon.txt ] ; echo $?
1

-s    #检查目录及文件是否存在且不为空
[root@lemon ~]# [ -s /etc/passwd ] ; echo $?
0
[root@lemon ~]# [ -s /etc ] ; echo $?
0
[root@lemon ~]# [ -s /etcc/passwd ] ; echo $?
1
[root@lemon ~]# [ -s /etcc ] ; echo $?
1

-O    #检查文件是否存在并且被当前用户拥有
测试省略……

-G    #检查文件是否存在并且默认组为当前用户组
测试省略……

-r    #检查文件是否存在且可读
测试省略……

-w    #检查文件是否存在且可写
测试省略……

-x    #检查文件是否存在且可执行
测试省略……

4. 逻辑运算

  • 逻辑运算注意事项:
    • 逻辑与 或 运算都需要两个或以上条件,逻辑非运算只能一个条件。
    • 口诀:
      • 逻辑与运算 <==> 真真为真 真假为假 假假为假
      • 逻辑或运算 <==> 真真为真 真假为真 假假为假
      • 逻辑非运算 <==> 真为假 假为真
&&    #逻辑与运算
[root@lemon ~]# [ 10 -eq 10 ] && [ 'lemon' == 'lemon' ] ; echo $?
0
[root@lemon ~]# [ 10 -eq 20 ] && [ 'lemon' == 'lemon' ] ; echo $?
1

||    #逻辑或运算
[root@lemon ~]# [ 10 -eq 10 ] || [ 'lemon' == 'lemon' ] ; echo $?
0
[root@lemon ~]# [ 10 -eq 20 ] || [ 'lemon' == 'lemon' ] ; echo $?
0
[root@lemon ~]# [ 10 -eq 20 ] || [ 'lemon' == 'tomcc' ] ; echo $?
1

!     #逻辑非运算
[root@lemon ~]# [ ! 10 -eq 10 ] ; echo $?
1
[root@lemon ~]# [ ! 10 -eq 11 ] ; echo $?
0

二、if 语法

1. 语法一: 单if语句

  • 适用范围:只需要一步判断,条件返回真干什么或者条件返回假干什么。

  • 语句格式:

if [ condition ];then           #condition 值为true or false
   commands
fi
  • 该语句翻译成汉语大意如下:
如果条件为真
那么
    执行commands代码块
结束
  • 通过一段代码来演示一下
[root@lemon ~]# vim if.sh 
#!/bin/bash
if [ 10 -eq 10 ];then
   echo "hello world"
fi
  • 执行结果
[root@lemon ~]# bash if.sh 
hello world

2. 语法二: if-else语句

  • 适用范围:两步判断,条件为真干什么,条件为假干什么。
if [ condition ];then
   commands1
else
   commands2
fi
  • 该语句翻译成汉语大意如下:
如果条件为真
那么
    执行commands1代码块
否则
    执行commands2代码块
结束
  • 通过一段代码演示一下
[root@lemon ~]# vim if.sh
#!/bin/bash
read -p "请输入数字:" number
if [ $number -eq 10 ];then
   echo "条件为真"
else
   echo "条件为假"
fi
  • 执行结果
[root@lemon ~]# bash if.sh 
请输入数字:10
条件为真

[root@lemon ~]# bash if.sh 
请输入数字:20
条件为假

3. 语法三: if-elif-else语句

  • 适用范围:多于两个以上的判断结果,也就是多于一个以上的判断条件。
if [ condition 1 ];then
   commands1
elif [ condition 2 ];then
   commands2
.......

else
   commandsX
fi
  • 该语句翻译成汉语大意如下:
如果 条件1 为真
      那么
         执行代码块1
如果 条件2 为真
      那么
         执行代码块2

以此类推的N个条件及对应的执行代码块

否则 【以上所有条件中没有一个满足的】
         执行代码块X
结束
  • 通过一段代码演示一下
[root@lemon ~]# vim if.sh 
#!/bin/bash
read -p "请输入数字:" number
if [ $number -eq 10 ];then
   echo "条件 1 为真"
elif [ $number -gt 10 ];then
   echo "条件 2 为真"
else
   echo "以上条件都为假"
fi
  • 执行结果
[root@lemon ~]# bash if.sh 
请输入数字:9
以上条件都为假

[root@lemon ~]# bash if.sh 
请输入数字:10
条件 1 为真

[root@lemon ~]# bash if.sh 
请输入数字:11
条件 2 为真

三、if 高级应用

if 命令, 双圆括号, 双中括号 条件测试

循环脚本控制语句

特殊条件表达式

  • true #当条件表达式为true时,那么代表条件表达式永远成立,为真; 【条件成立】

  • false #当条件表达式为false时,那么代表条件表达式永远不成立,为假;【条件不成立】

测试 continue、break、exit 语句的不同点

通俗点讲:break是立马跳出循环;continue是跳出当前条件循环,继续下一轮条件循环;exit是直接退出整个脚本

  • 代码如下
[root@lemon ~]# vim test.sh
#!/bin/bash
for i in {1..5};do
    if [ $i -eq 3 ];then
       $1
    fi
    echo "$i"
done
echo "循环体外命令"
  • 执行结果
# continue
[root@lemon ~]# bash test.sh continue
1
2
4
5
循环体外命令

# break
[root@lemon ~]# bash test.sh break
1
2
循环体外命令

# exit
[root@lemon ~]# bash test.sh exit
1
2

1. sleep N 脚本执行到该步休眠N秒

  • 作用:执行完上一条命令要停留的时间

  • 段代如下

[root@lemon ~]# vim for.sh 
#!/bin/bash
for i in `seq 9 -1 1`;do
    echo -n -e "倒计时: $i\r"
    sleep 1
done
  • 执行结果

2. continue 跳过循环中的某次循环

  • 作用:终止本次循环,继续执行下一次的循环

  • 代码如下,默认循环输出1-9,但是使用continue跳过输出5

[root@lemon ~]# vim for.sh #!/bin/bashfor i in {1..9};do    if [ $i -eq 5 ];then       continue    else       echo "$i"    fidone
  • 执行结果
[root@lemon ~]# bash for.sh 12346789

3. break 跳出循环继续执行后续代码

  • 作用:退出脚本中当前的循环体,继续执行循环体外的命令

  • 代码如下,默认循环输出1-9,当输出到5的时候跳出循环

#!/bin/bash
for i in {1..9};do
    if [ $i -eq 6 ];then
       break
    else
       echo "$i"
    fi
done
  • 执行结果
[root@lemon ~]# bash for.sh 
1
2
3
4
5
  • break N 跳出某个循环,用在嵌套循环环境,从内循环到外循环依次编号为1-N
[root@lemon ~]# vim for.sh 
#!/bin/bash
#脚本分三步执行
#1.没有break  那么脚本i=1的时候  内循环将无限循环,满屏幕haha
#2.内循环加break  终止内循环 内循环只执行一次 输出就会loop 1   haha   loop2  haha   ....
#3.内循环加break 2 终止外循环 输出loop 1  haha  脚本运行结束
for (( i=1; i<5; i++ ));do
    echo "#loop $i"
    for ((;;)); do
        echo "haha"
        break 2
    done
    sleep 3
done
  • 执行结果
[root@lemon ~]# bash for.sh 
#loop 1
haha

4. exit 退出当前脚本

  • 作用:直接退出脚本,循环体外的命令不会执行

  • 代码如下

[root@lemon ~]# vim for.sh 
#!/bin/bash
for i in {1..9};do
    if [ $i == 5 ];then
       exit 2    #后面的数字就是一个返回值,可用echo $?查看
    else
       echo "$i"
    fi
done
  • 执行结果
[root@lemon ~]# bash for.sh 
1
2
3
4
[root@lemon ~]# echo $?
2

shell流程控制-for循环语句

  • for循环介绍
  • for语法
  • 循环控制

脚本在执行任务的时候,总会遇到需要循环执行的时候,比如说我们需要脚本每隔五分钟执行一次ping的操作,除了计划任务,我们还可以使用脚本来完成,那么我们就用到了循环语句。

循环的优点:

  • 节省内存 10M脚本 1M脚本 哪个更剩内存 完成同一个任务
  • 结构更清晰
  • 节省开发时间成本

一、for 循环介绍

  • for的工作原理
很多人把for循环叫做条件循环,或者for i in 。其实前者说的就是for的特性,for循环的次数和给予的条件是成正比的,也就是你给5个条件,那么他就循环5次;后者说的是for的语法。

二、for语法

1. for 语法一

for i in value1 value2 ......;do
     commands
done
  • 接下来看段代码吧,循环输出1-9数字
[root@lemon ~]# vim for.sh
#!/bin/bash
for i in `seq 1 9`;do
    echo "number <==> $i"
done
  • 代码执行结果:
[root@lemon ~]# bash for.sh
number <==> 1
number <==> 2
number <==> 3
number <==> 4
number <==> 5
number <==> 6
number <==> 7
number <==> 8
number <==> 9

2. for语法二

for ((变量;条件;自增减运算));do
    代码块
done

来段代码理解一下,看下还是输出1-9

[root@lemon ~]# vim for.sh
#!/bin/bash
for ((i=1;$i<10;i++));do
    echo "number <==> $i"
done
  • 代码执行结果
[root@lemon ~]# bash for.sh
number <==> 1
number <==> 2
number <==> 3
number <==> 4
number <==> 5
number <==> 6
number <==> 7
number <==> 8
number <==> 9

for循环使用多个变量

[root@lemon ~]# vim for.sh
#!/bin/bash
for ((a=0,b=9;$a<10;a++,b--));do
    echo "number <==> $a  $b"
done
  • 代码执行结果
[root@lemon ~]# bash for.sh
number <==> 0  9
number <==> 1  8
number <==> 2  7
number <==> 3  6
number <==> 4  5
number <==> 5  4
number <==> 6  3
number <==> 7  2
number <==> 8  1
number <==> 9  0

for 无限循环 使用((;

标签:Shell,lemon,echo,sh,033,root,bash
From: https://www.cnblogs.com/ArMinLi/p/17571543.html

相关文章

  • Linux - Check If File Is Empty Or Not Using Shell Script
    Linux-CheckIfFileIsEmptyOrNotUsingShellScriptHowdoIcheckifafileisemptyornotusingbashorkshshellscriptunderaUNIX/Linux/macOS/OSX/BSDfamilyofoperatingsystems?HowdoIcheckifafileisemptyinBash?Youcanuse......
  • Day 3: Shell条件语句和循环
    学习目标学习内容1.条件语句if语句case语句2.循环结构for循环while循环3.练习任务大树哥个人信息学习目标学习Shell中的条件语句,如if语句和case语句。理解循环结构,如for循环和while循环。练习编写脚本,包括条件判断和循环执行。学习内容今天我们将学习Shell中的条件语......
  • CentOS-Mysql 自动备份-shell 脚本
    功能说明:在服务器A上,每天自动运行一个shell脚本;备份数据库db;然后将sql文件放到另一台服务器B上。新建文件:mysql_backup.sh内容是:#!/bin/bashHOST=127.0.0.1USERNAME=rootPASSWORD=rootDBNAME=adverserverHost=123.123.123.123DATE=$(date+%Y%m%d)OLDDATE=$(date-d......
  • Linux shell | 竖线管道符号放变量 无法访问'|': 没有那个文件或目录 无法访问'wc':
    工作中遇到一个实际问题,文本编码转换。原始命令:catutf8.log|iconv-c-fUTF-8-tGBK|teegbk.log因为某种(方便修改、方便替换)原因,想把“|iconv-c-fUTF-8-tGBK|”命令这段,想放到变量里,做到一处修改处处生效的效果。pipe="|iconv-c-fUTF-8-tGBK|"catutf......
  • mssql的xp_cmdshell扩展
    introductionxp_cmdshellextension:storedprocedureexecutescommandstringasanoperatingsystemcommandinshell andretirevealloutputastextlinesdetermineifcurrentmssqlhasxp_cmdshellareturnvalueof1indicatestheextensionisxp_cmdsh......
  • Windows下spark能运行但打不开spark-shell
    解决Windows下spark能运行但打不开spark-shell问题作为一名经验丰富的开发者,我将教你解决Windows下spark能够运行但无法打开spark-shell的问题。下面是整个解决流程,可以通过表格的形式展示步骤:步骤操作步骤1检查Java环境变量步骤2检查Hadoop环境变量步骤3检......
  • PowerShell Sql server 系列一:连接SQl
    前置条件PowerShell基础知识。模块,参数,凭证Sqlserver基础知识,SSMS操作熟练labSqlserver2017-2022Dev版本PowerShell5.1以上安装dba模块Install-Module-Namedbatools测试和连接sql测试sql#Windows账户连接Test-DbaConnection-SqlInstancekite\mssqls......
  • webshell工具流量特征
    常见的webshell管理工具及流量特征菜刀作为老牌Webshell管理神器,中国菜刀的攻击流量特征明显,容易被各类安全设备检测,实际场景中越来越少使用,加密Webshell正变得日趋流行。最开始使用明文传输,后来采用base64加密UA字段通常为百度,火狐存在特征字符请求体中存在eavl,base64......
  • Xshell 连接Vmware虚拟机下Ubuntu,出现拒绝密码的问题:
    参考解决方法打开WiredSettings将IPV4,中的设置不选择DHCP协议,而是选择manal手动地址按照details中的填即可,子网掩码设置为255.255.255.0打开文件/etc/ssh/sshd_config找到这四行语句,去掉前面注释#,并修改为LoginGraceTime2mPermitRootLoginyesStrictModesyes........
  • Linux反弹shell的简单复现
    前情提要本文是对https://blog.csdn.net/cosmoslin/article/details/121269178这篇文章的一个简单复现,具体原理在本文中不怎么会提到。师傅如果要验证的话,注意将下文的IP等改为自己对应的IP,还有其他的因素可能也要根据自己的情况做点修改。然后因为靶机或环境配置可能不同,各位师......