shell脚本学习

变量名命名规则

1.名称定义要见名之意,按照规则来,不得引用保留关键字(help检查保留字)

2.只能包含数字、字母、下划线

3.不能以数字开头

4.不能用标点符号

5.变量名严格区分大小写

有效的变量名:

NAME_DATA

_change

_change1

chAoE1

无效的变量名

?change

chao*ge

变量的作用域 

本地变量:只针对当前的shell进程,切换shell 变量会丢失

 环境变量:也称为全局变量,针对当前shell以及其任意子进程,环境变量也分自定义、内置两种环境变量

局部变量:针对在shell函数或者shell脚本中定义的

位置参数变量:用于shell脚本中传递的参数

特殊变量:shell内置的特殊功效变量

$?

        返回值0:成功

         返回这1-255:错误码

一般在shell脚本中用于上一条命令是否执行成功

自定义变量:name=value

变量引用:${name}、$name

        双引号,变量名会替换为变量值

        例如:在shell环境中

               我们自定义变量  n1=1    n2=2

              这个时候我们使用n3="$n1"

               我们打印n3 命令:echo  $n3 结果也是1,这句话就是"$n1"其实是获取的n1的值,我们将这个值赋值给了n3,所以直接打印n3的值也是1

               但是如果我们使用单引号n4='$n2',那么我们打印的结果则是$n2,不会进行替换

 注意本地变量,当前shell:

单引号变量,不识别特殊语法

双引号变量,能识别特殊语法

无引号,连续的符号可以不加引号

反引号,引用命令执行结果,等于$()用法

如下:

[root@VM-28-7-centos ~]# name="lsz"
[root@VM-28-7-centos ~]# n1='${name}'
[root@VM-28-7-centos ~]# echo n1
${name}


# 在上述中,我们使用${name}是特殊语法可以取出name的值,但是单引号并没有识别出来,我们打印n1的值为${name}

[root@VM-28-7-centos ~]# n2="${name}"
[root@VM-28-7-centos ~]# echo $n2
lsz
我们使用了双引号,那么就会识别特殊语法

关于shell的执行作用域: 

1.每次调用bash/sh 解释器执行脚本,都会开启一个子shell,因此不保留当前的shell变量,通过pstree命令可以检查进程树

2.调用source或者点符号是在当前shell环境加载脚本,因此会保留变量

# 演示
1.开启子shell的执行方式
[root@VM-28-7-centos ~]# vim book.sh
[root@VM-28-7-centos ~]# cat book.sh 
#!/bin/bash
name="大西瓜"
[root@VM-28-7-centos ~]# name="小西瓜"
[root@VM-28-7-centos ~]# echo $name
小西瓜
[root@VM-28-7-centos ~]# sh book.sh 
[root@VM-28-7-centos ~]# echo $name
小西瓜

# 我们定义了一个book.sh,里面写入了一个变量名,当我们执行了sh文件后,他会开启子shell执行sh脚本,因此我们在当前shell的环境中name的值没有发生改变

2.不开启子shell的执行方式
[root@VM-28-7-centos ~]# source book.sh 
[root@VM-28-7-centos ~]# echo $name
大西瓜

# 我们使用了source 执行sh脚本就不会开启子shell执行,使用的当前shell解释器,就会将当前已经定义的name值进行改变

环境变量

环境变量一般指的是export内置命令导出的变量,用于定义shell的运行环境,保证shell命令的正确性

shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用

环境变量可以在命令行中临时创建,但是用户退出shell终端,变量即丢失,如果想要永久生效,需要修改环境变量配置文件

* 用户个人配置文件:~/.bash_profile 、~/.bashrc 远程登录用户特有文件

* 全局配置文件 /ect/profile 、 /etc/bashrc ,切系统建议最好创建在/etc/profile.d/ 而非直接修改主文件,修改全局配置文件,影响所有登录系统的用户

检查系统环境变量的命令

1.set,输出所有变量,包括全局变量/局部变量

2.env 只显示全局变量

3.declare 输出所有的变量,如同set

4.ecport 现实和设置环境变量值

撤销环境变量

unset 变量名 删除变量或函数

设置只读变量

readonly  只有shell结束,只读变量失效

特殊参数变量

$0 获取shell脚本文件名,以及脚本路径
$n 获取shell脚本的第n个参数,n在1-9之间
$# 获取执行的shell脚本后面的参数总个数
$* 获取shell脚本所有参数,不加引号等同于$@作用,加上引号"$*"作用
$@ 不加引号,效果同上,加引号,是接受所有参数为独立字符串,如"$1" "$2" ,空格保留



$*与$@ 的区别:

$*会将所有的参数从整体上看做是一份数据,而不是把每个参数都看做一份数据,按照python中的理解可以理解为他将所有的参数放到了同一个字符串里面

$@会将每个参数都看做一份数据,彼此直接是独立的,按照python的理解可以理解为他输出了多个字符串,每个字符串是一个参数


如下所示:
[root@VM-28-7-centos ~]# cat book.sh 
#!/bin/bash
echo "print echo param from \"\$*\""

# 这里是一个for循环
for var in "$*"
do 
   echo "$var"
done

echo "print echo param from \"\$@\""
for var in "$@"
do 
    echo "$var"
done
[root@VM-28-7-centos ~]# bash book.sh 11 12 13 14
print echo param from "$*"
11 12 13 14
print echo param from "$@"
11
12
13
14
# 使用for循环我们就可以看出来两者的区别

特殊状态变量

$? 上一次命令执行状态返回值,0正确,非0失败
$$  当前shell脚本的进程号
$!  上一次后台进行的PID
$_  再次之前执行的命令,最后一个参数

查找方式 man bash
    搜索Special Parameters

shell子串

bash一些基础的内置命令

echo:打印输出

eval:执行多个命令

exec:不创建子进程,执行后续命令,并且执行完毕,自动exit

export:

read

shift

echo
-n:不换行输出
-e:解析字符串中的特殊符号

\n 换行
\r 回车
\t 制表符 4个空格
\b 退格

shell子串的花式语法

字符串截取

${变量}:        返回变量值

${#变量}:        返回变量长度,字符长度

${变量:start}        返回变量start数值之后的的字符

${变量:start:length}        提供start之后的length限制的字符

${变量#word}        从变量开头删除最短匹配的word子串

${变量##word}        从变量开头,删除最长匹配的word

${变量%word}        从变量结尾删除最短的word

${变量%%word}        从变量结尾开始删除最长匹配的word

${变量/pattern/string}        用string代替第一个匹配的pattern

${变量//pettern/string}        用string替代所有的pattern

[root@VM-28-7-centos ~]# echo $name
大西瓜
[root@VM-28-7-centos ~]# echo ${#name}
3
[root@VM-28-7-centos ~]# echo ${name:2}
瓜
[root@VM-28-7-centos ~]# echo ${name:1:1}
西
[root@VM-28-7-centos ~]# echo ${name#大}
西瓜

[root@VM-28-7-centos ~]# name="yuchao"
[root@VM-28-7-centos ~]# echo ${name#yu}
chao
[root@VM-28-7-centos ~]# echo ${name/yu/zh}
zhchao

# 可以理解为python的字符串操作,
${#name}代表是len,${name#大}切割,split,
${name/yu/zh}替换replace,
{name:1:1}从索引1开始截取截取长度为1

# 注意这些操作并不会影响字符串本身
[root@VM-28-7-centos ~]# echo ${name/yu/zh}
zhchao
[root@VM-28-7-centos ~]# echo $name
yuchao

 案例:批量替换文件名

[root@VM-28-7-centos ~]# ls
book_one_fin.sh  book_three_fin.sh  book_two_fin.sh  demo.text  mysql57-community-release-el7-10.noarch.rpm
[root@VM-28-7-centos ~]# vim udapte_file_name.sh
[root@VM-28-7-centos ~]# bash udapte_file_name.sh 
[root@VM-28-7-centos ~]# ls
book_one.sh  book_three.sh  book_two.sh  demo.text  mysql57-community-release-el7-10.noarch.rpm  udapte_file_name.sh

[root@VM-28-7-centos ~]# cat udapte_file_name.sh 
#!/bin/bash/
# 获取所有fin结尾的文件名
ls_result=`ls *fin.sh`
for result in $ls_result
do 
    mv $result ${result//_fin/}
done

# 我们在sh文件中首先获取ls 命令的执行结果,然后进行for,按照字符串的操作进行批量替换,对于python来说就是os获取所有名字然后使用rename就可以了

特殊shell拓展变量

变量的处理

如果parameter变量值为空,返回word字符串

${parameter:-word}

如果para变量为空,则word代替变量值,且返回其值

${parameter:=word}

如果para变量为空,word当做stderr输出,否则输出变量值

用于设置变量为空导致错误时,返回的错误信息

${parameter:?word}

如果para变量为空,什么都不做,否则word返回

${parameter:+word}

内置命令、外置命令

内置命令:在系统启动时就会加载入内存,常驻内存,执行效率更高,但是占用资源

外置命令:用户需要从硬盘中读取程序文件,再读入内存加载

执行脚本的方式

source

. test.sh 

bash test.sh

./test.sh   # 这样的方式需要添加可执行权限

sh  ./test.sh

 Shell运算

用于数值计算的命令

双小括号

[root@VM-28-7-centos ~]# cat test.sh 
#!/bin/bash

i=2
((i=i+1))
echo $i


[root@VM-28-7-centos ~]# sh test.sh 
3

 上面就是简单用法,其实就跟我们python是差不多的,就是python可以直接用I=I+1,然后直接print变量名,shell需要用$才能取出来变量的值

简单逻辑运算
[root@VM-28-7-centos ~]# echo $((6>7))
0
[root@VM-28-7-centos ~]# echo $((6<7))
1

# 可以理解为python的True或者False,如果为真则为True也就是1,如果为假则为False就是0
复杂逻辑运算
[root@VM-28-7-centos ~]# echo $((6<7&&2>3))
0
[root@VM-28-7-centos ~]# echo $((6<7&&2<3))
1

# &&表示两边都成立则为1,如果有一边不成立则为0,相当于python的and



[root@VM-28-7-centos ~]# echo $((6<7||2<3))
1

# || 或的意思,只要符号两边有一个成立则就为1,相当于python的or
基本运算
[root@VM-28-7-centos ~]# cat test.sh 
#!/bin/bash

# 加法
echo $((3+4))
# 减法
echo $((4-3))
# 乘法
echo $((3*4))
# 除法
echo $((10/3))
# 取余
echo $((10%3))


[root@VM-28-7-centos ~]# sh test.sh 
7
1
12
3
1

# 上面基本运算符,$的作用是取值,需要记得就是除法,/是用来或者商的,%用来获取余数
特殊符号运算

++   +1

--      -1

坑:

    ++a,先计算+1,然后在赋值给a

     a++,先对变量a进行操作再进行+1

示例:

[root@VM-28-7-centos ~]# cat test.sh 
#!/bin/bash

a=1
((a++))
echo $a
b=1
echo $((b++))
echo $b

[root@VM-28-7-centos ~]# sh test.sh 
2
1
2
我们分别进行了3次打印,a++很好理解直接+1然后赋值给了a,a本来是1,然后加1就是2,

echo $((b++))  他是首先打印b,然后再计算,所以打印初始的b是1

echo $b 我们再对b进行取值,那他获取就是b+1以后的

 简单的数字脚本
#!/bin/bash

read -p "请输入你的数字" number
if [ $number>10 ]
 then
  echo "你输入的数字大于10了"
fi


# 这里用到了read  -p  表示代码走到这里会让用户输入一个数字并赋值给number这个变量

# if 后面用[ ]中括号来进行条件判断,then,表示条件成立需要执行,fi表示if的结束

  • 10
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值