linux shell编程规范和变量以及判断语句

1、shell简述

1.1什么是shell

翻译官功能,与内核进行沟通的应用程序。把代码翻译为二进制,让内核处理,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。

1.2linux的shell:/etc/shells

用户使用命令时,系统会检测这个文件得到内容,命令在里面才可以使用相关命令。
bash(/bin/bash)是目前大多数 Linux 版本采用的默认 Shell。
在这里插入图片描述

2、shell脚本

2.1shell脚本文件格式:.sh

2.2运行shell脚本命令:

1.sh first.sh
2.bash first.sh
3.source first.sh
4../first.sh(需要赋予权限)

2.3运行一个简单的shell脚本

vim test.sh  //创建一个sh类型的文件

在这里插入图片描述

bash test.sh  //运行刚才创建的文件

在这里插入图片描述

2.3脚本的执行逻辑及执行方式

脚本执行逻辑
1. 顺序执行:程序按从上到下顺序执行
2. 选择执行:程序执行过程中,根据条件的不同,进行选择不同分支继续执行
3. 循环执行:程序执行过程中需要重复执行多次某段语句

执行方式
指定路径去执行文件(需要有执行权限)

   [root@localhost ~]# chmod +x /root/host.sh    加权限
   指定相对路径./host.sh
   指定绝对路径/root/host.sh

指定解释器去执行(不需要权限)

#!/bin/bash 此处指定的shell为bash,则bash不需要权限也可以执行

source 和 . (不需要权限)

#执行方式三#
source 脚本名(绝对路径)
source /root/host.sh 
或者
. /host.sh 

2.4Shell脚本错误调试

  • 语法错误
    会导致后续的命令不继续执行,可以用bash -n 检查错误,提示的出错行数不一定是准确的。

  • 命令错误
    默认后续的命令还会继续执行,用bash -n 无法检查出来 ,可以使用 bash -x 进行观察。

    扫描二维码关注公众号,回复: 16561977 查看本文章
  • 逻辑错误
    只能使用 bash -x 进行排错。

bash -x    #模拟执行,可以逐条排错
bash -n    #检查语法错误

2.5脚本的优点

1.自动化运维
2.批量化重复操作可以编写脚本结合计划任务自动周期运行
3.减轻管理员工作量
4.提高处理文本文件的速度
5.避免配置出错

2.6运算符

1.加法 +
2.减法 -
3.乘法 \ *
4.除法 /(只会显示整数,除不尽为0)
5.取余 (取模)% 
(1) let var=算术表达式
let sum=1+2
sum=1+2
(2) $((var=算术表达式)) 和上面等价
((sum=1+2))
echo $sum
(3) var= $[算术表达式]
(4) var=$((算术表达式))
(5) var=$(expr arg1 arg2 arg3 ...)
(6) var= expr arg1 arg2 arg3 ...
(7) echo '算术表达式' | bc

  $[ ]
  $(())
  $(expr 1 2 3)

#let
[root@localhost ~]#a=1
[root@localhost ~]#b=2
[root@localhost ~]#let z=a+b
[root@localhost ~]#echo $z
3
[root@localhost ~]#let z=$[a-b]
[root@localhost ~]#echo $z
-1
[root@localhost ~]#let z=$((a-b))
[root@localhost ~]#echo $z
-1

#expr
[root@localhost ~]#a=1
[root@localhost ~]#b=2
[root@localhost ~]#expr $a + $b
#加减乘除前后有空格
3

[root@localhost ~]#echo "6*3"|bc
18
echo  $[RANDOM%34 +1]

let 支持加加减减 使用较多
[root@localhost ~]#i=1
[root@localhost ~]#let i++
[root@localhost ~]#echo $i
2
[root@localhost ~]#i=1;let i++;echo $i
2
[root@localhost ~]#i=1;let ++i;echo $i
2
[root@localhost ~]#i=100;let j=i++;echo $i $j
101 100
[root@localhost ~]#i=100;let j=++i;echo $i $j
101 101
#i++ 是先赋值给j后再加     ++i是加后再赋值

i++  是先赋值再加
++i  是加后再赋值

i=$(expr 12  \ *  5 )
i=$((12 * 5))
i=$[12 * 5]
let i=12*5
i++ 相当于 i=$[ $i+1 ]
i-- 相当于 i=$[ $i - 1 ]
i+=2 相当于 i=$[ $i+2 ]

2.7运算法则

1.加法: num1 + num2
2.减法:num1 - num2
3.乘法:num1 \ * num2
4.整除:num1 / num2
5.取余(求模):num1 % num2 (求 num1 除以 num2 的余数)

在这里插入图片描述

3、重定向与管道符

3.1重定向

类型 设备文件 文件描述编号 默认设备
标准输入 /dev/stdin 0 键盘
标准输出 /dev/stdout 1 显示器
标准错误输出 /dev/stderr 2 显示器
类型 操作符 用途
重定向输入 < 从指定的文件读取数据,而不是从键盘输入
重定向输出 1> 将输出结果保存到指定的文件(覆盖原有内容)
>> 将输出结果追加到指定的文件尾部
标准错误输出 2> 将错误信息保存到指定的文件(覆盖原有内容)
2>> 标准错误输出结果追加到指定的文件尾部
混合输出 &>无论对错都可以重定向 将标准输出、标准错误的内容保存到同一个文件中

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

[root@localhost ~]#ls /data /error >all.log 2>&1
#既有错误也有正确 &符号表示分隔符
[root@localhost ~]#cat all.log 
ls: 无法访问/error: 没有那个文件或目录

[root@localhost ~]#ls /data /error >all.log 2>1
#如果没有&会生成一个 1文件 将错误导入

在这里插入图片描述

3.2管道符

| :主要用在处理文本上,将管道符号“|”左侧的命令输出的结果,作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道。

将user用户的密码改为123123

在这里插入图片描述

4、变量

4.1常见的变量类型

自定义变量:由用户自己定义,修改和使用
环境变量:由系统维护,用于设置工作环境
只读变量:只可以读取不可以更改
位置变量:通过命令行给脚本传递参数
预定义变量:Bash中内置的一类变量,不能修改    有些规定好的变量 放在那里让你使用

4.2命名要求

- 区分大小写
- 不能使程序中的保留字和内置变量:如:if, for,hostname   命令  a=
- 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反
- 不要使用内置的变量,使用英文尽量使用词义通俗易懂,PATH              
- 大驼峰 StudentFirstName 
- 小驼峰 studentFirstName 
- 下划线 student_name
弱引用和强引用
"$name " 弱引用,其中的变量引用会被替换为变量值
'$name ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串

在这里插入图片描述
在这里插入图片描述

4.3 read -p

在这里插入图片描述
在这里插入图片描述

4.4将局部变量变为全局变量

局部变量:新定义的变量只在当前的shell环境中有效,当进入子程序或新的shell环境中,局部变量将无法再起作用。
全局变量:在新的shell环境中可以继续使用。
通过内部命令export将局部变量为全局变量

格式1:export  变量名
格式2:export  变量名=变量值
#可以使用pstree 查看shell的环境
#输入bash进入子shell
#ctrl+D组合exit 退出子shell
[root@localhost opt]# abc=123
[root@localhost opt]# echo $abc 
123
[root@localhost opt]# bash
[root@localhost opt]# echo $abc
为空
[root@localhost opt]# exit
exit
[root@localhost opt]# echo $abc
123
[root@localhost opt]# export abc
#export  变量名      定义全局变量
[root@localhost opt]# bash
[root@localhost opt]# echo $abc
123

4.5环境变量

环境变量由系统提前创建,用来设置用户的工作环境。

env   #可以看到当前所有的环境变量

4.5.1常用的环境变量

  • $USER 表示用户名称
    在这里插入图片描述
  • $HOME 表示用户的家目录
    在这里插入图片描述
  • $LANG 表示语言和字符集
    在这里插入图片描述
  • $PWD 表示当前所在工作目录
    在这里插入图片描述
  • $PATH 表示可执行用户程序的默认路径
    在这里插入图片描述

4.5.2环境变量的全局配置文件

#配置文件位置
/etc/profile 
##修改此文件,全局生效,可用于长期变更或设置环境变量

4.6只读变量

  • 将变量声明为只读(read-only)后,不能再修改变量的值。
readonly 变量名 #将变量声明为只读变量

4.7位置变量

$1, $2, $3, … $n 表示命令行参数的位置值
$1 表示第一个参数,$2 表示第二个参数,以此类推。
当n大于9时,需要加上{ },比如第十个位置,要用 ${10}表示

#以shell脚本为例
#!/bin/bash
echo "$1"            #位置1
echo "$2"            #位置2
echo "$3"            #位置3
echo "${10}"         #位置10
echo "$10"           #位置1和0

在这里插入图片描述

4.8预定义变量

系统帮你定义好了 拿来用就可以了

  • $*:表示所有位置参数的内容看成一个整体返回 返回所有
  • $@:表示所有位置参数的内容分割成n份,每份作为一个独立的个体返回 返回所有
  • $?:表示前一条命令执行后的返回状态,返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常
  • $#:表示命令行中位置参数的总个数
  • $0:表示当前执行的脚本或程序的名称 当前脚本的名字
  • $$:当前进程id
  • $!: 后台任务最后一个id

5、条件语句

5.1测试

test 测试文件的表达式 是否成立
格式1:test  条件表达式
格式2:[  条件表达式  ]
注意[]空格,否则会失败
测试 是否成功使用 $?  返回值
[ 操作符 文件或目录 ]
help test
操作符:
-d:测试是否为目录(Directory)
-e:测试目录或文件是否存在(Exist)
-a:测试目录或文件是否存在(Exist)
-f:测试是否为文件(File)
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write-x:测试当前用户是否有权限执行(eXcute)
-L: 测试是否为软连接文件

属性测试补充:
-s FILE #是否存在且非空
-t fd #fd 文件描述符是否在某终端已经打开
-N FILE #文件自从上一次被读取之后是否被修改过
-O FILE #当前有效用户是否为文件属主
-G FILE #当前有效用户是否为文件属组

若真,则状态码变量 $? 返回0
若假,则状态码变量 $? 返回1

在这里插入图片描述
在这里插入图片描述

[root@localhost ~]# test -e qiuhe.sh &&echo "yes"
yes
&&表示且的意思 前面的表达式成立才会输出yes

5.2比较整数数值

[ 整数1 操作符 整数2 ] 公式

  • -eq:第一个数等于(Equal)第二个数
  • -ne:第一个数不等于(Not Equal)第二个数
  • -gt:第一个数大于(Greater Than)第二个数
  • -lt:第一个数小于(Lesser Than)第二个数
  • -le:第一个数小于或等于(Lesser or Equal)第二个数
  • -ge:第一个数大于或等于(Greater or Equal)第二个数
[  整数1  操作符  整数2  ]
[root@test1 ~]# a=2        实例
[root@test1 ~]# b=3
[root@test1 ~] [ $a -eq $b ]
[root@test1 ~]# echo $?
1
[root@test1 ~]# [ 2 -le 3 ]
[root@test1 ~]# echo $?
0

在这里插入图片描述

5.3字符串比较

常用的测试操作符

  • =:字符串内容相同
  • !=:字符串内容不同,! 号表示相反的意思
  • -z:字符串内容为空
  • -n: 字符是否存在

格式
[ 字符串1 = 字符串2 ] 是否相同
[ 字符串1 != 字符串2 ] 是否不相同
[ -z 字符串 ] 是否为空
[ -n 字符串 ] 字符是否存在
[root@localhost data]#str1=wang
[root@localhost data]#str2=zhou
[root@localhost data]#[ $str1 = $str2 ]
[root@localhost data]#echo $?
1

[root@localhost etc]# [ $USER = root ]&& echo true
true
[root@localhost etc]# [ $USER != root ]&& echo true

[root@localhost etc]# read -p "yes/no:" ack
yes/no:
[root@localhost etc]# echo $ack 

[root@localhost etc]# [ -z $ack ] && echo true 
true
[root@192 ~]# read -p "是否覆盖当前文件 (yes/no)" ACK
是否覆盖当前文件 (yes/no)yes
[root@192 ~]# [ $ACK = "yes" ] && echo "覆盖"
覆盖
[root@192 ~]# read -p "是否覆盖当前文件 (yes/no)" ACK
是否覆盖当前文件 (yes/no)no
[root@192 ~]# [ $ACK = "no" ] && echo "不覆盖"
不覆盖

5.4逻辑测试(短路运算)

格式1:[ 表达式1 ] 操作符 [ 表达式2 ] …
格式2:命令1 操作符 命令2 …

常见条件

  • -a或&&:逻辑与,“而且”的意思全真才为真
  • -o或||:逻辑或,“或者”的意思一真即为真
  • !:逻辑否
  • [root@192 ~]# [ ! -d mmm ] && echo “yes”
    yes
[root@localhost etc]# [ 4 -lt 5 ]&&echo true || echo false
true
[root@localhost etc]# [ 4 -gt 5 ]&&echo true || echo false
false
[root@localhost etc]# [ 4 -gt 5 ]&& echo true ||echo false
false

|| 只有前面不成立时才会执行后面的操作

合并条件
[root@localhost etc]# [ $a -ne 1 ]&&[ $a != 2 ]
[root@localhost etc]# echo $?
0
[root@localhost etc]# [ $a -ne 1 -a  $a != 2 ]
[root@localhost etc]# echo $?
0
[root@localhost etc]# [[ $a -ne 1 &&  $a != 2 ]]
[root@localhost etc]# echo $?
0

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.5if语句的结构

5.5.1if语句

单分支if语句:
       if
       then
       fi

双分支if语句:
      if [ ]
      then
      else
      if

多分支if语句:
      if [ ]
      then
      elif [ ]
      then
      fi

5.5.2case

语句格式:case 变量 in
        模式1)
          命令
          ;;
          模式2)
          命令
          ;;
          *)
          命令
          ;;
          esac

case支持glob风格的通配符:
* 任意长度任意字符
? 任意单个字符
[0-9] 指定范围内的任意单个字符
|   或者,如: a|b

在这里插入图片描述

5.2.3echo

echo -n   表示不换行输出
echo -e   表示输出转义符
常用的转义符
选项 作用
\r 光标移至行首,并且不换行
\s 当前shell的名称,如bash
\t 插入Tab键,制表符
\n 输出换行
\f 换行,但光标仍停留在原处
\ 表示插入"\"本身转义
\b 表示退格 不显示前一个字符
\c 抑制更多的输出或不换行
[root@localhost ky15]#echo -e "12345\b678"
##退格删除前面的字符
1234678
[root@localhost ky15]#echo -e "12345\b\b678"
123678
[root@localhost ky15]#echo -e "12345\b\b\b678"
12678
[root@localhost ky15]#echo -e "12345\b\b\b\b678"
16785
###注意退格键和末尾的字符相关,超过末尾的字符数量 会出bug 了解即可

[root@localhost ky15]#echo -e "12345678\c"
12345678[root@localhost ky15]#echo -e "1234\c5678"
1234[root@localhost ky15]#
###\c 注意 使用在数字中间会把后面内容删除

5.2.4date

date查看当前系统时间

  • -d 你描述的日期,显示指定字符串所描述的时间,而非当前时间
  • %F 完整日期格式,等价于 %Y-%m-%d
  • % T 时间(24小时制)(hh:mm:ss)
[root@localhost ~]# date -d '-1 day' +%F 
2021-10-21

[root@localhost ~]# date  +%F 
2021-08-19
[root@localhost ~]# date -d '1 day ' +%F-%T
2021-08-20-23:28:42
[root@localhost mnt]# date -d "-3 day"      前三天
2021年 08月 18日 星期三 11:30:15 CST
[root@localhost mnt]# date -d "+3 day"  后三天
2021年 08月 18日 星期三 11:30:15 CST
[root@localhost data]#date -d '1 day ' +%F'     '%T
2021-10-22     00:45:37

6、现实用例

检查用户家目录中的 test.sh 文件是否存在,并且检查是否有执行权限
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_62231324/article/details/132259490