【shell 编程大全】脚本交互 以及表达式

脚本交互 以及表达式

1. 概述

嗨,我又来继续分享了。今天分享的内容是脚本交互,再开始接下来的分享开始之前,让我们来回顾下上一次(【shell 编程大全】内容格式化以及多样化输出)的内容:

  • 内容格式化
    • 重定向
    • 管道符
    • 后台执行
    • 信息符号
  • 输入格式化
    • eof原理
    • cat 实践
    • tee 实践
  • 输出格式化
    • echo 解读
    • 颜色输出
    • 颜色分类
    • printf 格式化

2. 登录shell 关联配置文件

文本讲述下 如果你要登录shell,会执行哪些文件以及每个文件都是干什么的

# 系统级别生效配置文件
# 系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行 
/etc/profile
# 被/etc/profile文件调用,执行当前目录下所有的文件中关于shell的设置
/etc/profile.d/*.sh
# 为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取
/etc/bashrc

# 用户级别生效配置文件
# 设定用户专用的shell信息,当用户登录时,该文件仅仅执行一次
~/.bash_profile
# 该文件包含用户专用的bash信息,当登录时以及每次打开新的shell时,该文件被读取
~/.bashrc

# 用户退出生效配置文件
# 当每次退出系统(退出bash shell)时,执行该文件.
~/.bash_logout
# 用户登录时自动读取其中的内容并加载到内存hiatory记录中logout时将内存中的history记录写入该文件中
~/.bash_history

下面是打印结果

在这里插入图片描述

  • 先执行系统级别的配置文件 /etc/profile. 在该文件中执行/profile.d 下的所有shell。
  • 执行文件夹/profile.d 下的所有的shell
  • 执行文件配置 /etc/bashrc
  • 开始执行用户级别的文件,~/.bash_profile.
  • 最后执行文件~/.bashrc

3. 什么是子shell

对于一些临时性的场景,我们在临时性的环境中,做一些操作,但是不希望对外部的环境造成影响,这个时候我们就涉及到了一些临时shell环境的实践。关于临时shell环境的创建,我们可以借助于()方法来实现。

一般我们要实现临时环境有以下两种方式:

  1. 启动子shell。(命令列表),在子shell中执行命令列表,退出子shell后,不影响后续环境操作。
  2. 不启动子shell。{命令列表}, 在当前shell中运行命令列表,会影响当前shell环境的后续操作。

案例演示

[root@localhost ~]# echo ${name}

[root@localhost ~]# (export name=lihh; echo ${name};)
lihh
[root@localhost ~]# echo ${name}

[root@localhost ~]# 

上述实例是启动子shell的情况下,在符号() 中定义的变量,不会影响到外部

[root@localhost ~]# echo ${name}

[root@localhost ~]# { export name=lihh; echo ${name}; }
lihh
[root@localhost ~]# echo ${name}
lihh
[root@localhost ~]# 

上述示例是不启用子shell的情况,在符号{}内部定义的变量,会影响外面的

4. umask 修改默认权限

认识umask

umask指的是文件权限默认的掩码,默认的值是022

  • 默认创建的目录是777-022=755
    默认创建的文件是666-022-644

示例

[root@localhost day06]# umask
0022
[root@localhost day06]# touch file1
[root@localhost day06]# 
[root@localhost day06]# mkdir folder1
[root@localhost day06]# ll
total 0
-rw-r--r--. 1 root root 0 Feb 13 15:20 file1
drwxr-xr-x. 2 root root 6 Feb 13 15:20 folder1
[root@localhost day06]# 

通过上述示例,生成的文件默认权限就是644,生成文件夹默认权限就是755

让我们来修改下 umask 试试

[root@localhost day06]# umask 666
[root@localhost day06]# umask
0666
[root@localhost day06]# touch file2
[root@localhost day06]# mkdir folder2
[root@localhost day06]# ll
total 0
----------. 1 root root 0 Feb 13 15:23 file2
d--x--x--x. 2 root root 6 Feb 13 15:23 folder2

5. read基础

read命令是用于从终端或者文件中读取输入的内建命令,read命令读取整行输入,每行末尾的换行符不被读入。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY

read 命令格式如下:

    read				从标准输入读取一行并赋值给特定变量REPLYread answer			从标准输入读取输入并赋值给变量answer。
    read first last		从标准输入读取内容,将第一个单词放到first中,其他内容放在last中。
    read -s passwd		从标准输入读取内容,写入passwd,不输入效果
    read -n n name		从标准输入读取内容,截取n个字符,写入name,超过n个字符,直接退出
    read -p "prompt"	打印提示,等待输入,并将输入存储在REPLY中。
    read -r line		允许输入包含反斜杠。
    read -t second		指定超时时间,默认是秒,整数
    read -d sper		指定输入信息的截止符号

实战

[root@localhost day06]# cat tshell001.sh 
#!/bin/bash

# 写交互命令的子shell

echo "======================= 请输入登录信息 ========================="
read -p "请输入账号:" account
read -s -t 20 -p "请输入密码:" password
echo ""
echo "======================= 输入结束       ========================="

echo "您输入的账号是:${account}"
echo "您输入的密码是:${password}"
[root@localhost day06]# /bin/bash ./tshell001.sh 
======================= 请输入登录信息 =========================
请输入账号:lihh
请输入密码:
======================= 输入结束       =========================
您输入的账号是:lihh
您输入的密码是:123456

6. 表达式

6.1 简单计算表达式

6.1.1 $[]

$[]方法,常用于整数计算场景,适合不太复杂的计算,运算结果是小数的也会自动取整。

格式

# 格式1
$[计算表达式]

# 格式2
a=$[变量名a+1]

示例

[root@localhost day06]# echo $[100/2]
50
[root@localhost day06]# echo $[99/2]
49
[root@localhost day06]# num=1
[root@localhost day06]# echo ${num}
1
[root@localhost day06]# num=$[ num+1 ]
[root@localhost day06]# echo ${num}
2
[root@localhost day06]# 
6.1.2 let

格式

# 格式
let	变量名a=变量名a+1

示例

[root@localhost day06]# echo ${num}

[root@localhost day06]# num=1
[root@localhost day06]# let num=num+1
[root@localhost day06]# echo ${num}
2
[root@localhost day06]# 
6.1.3 (())

此符号的用法跟let 是保持一致的

[root@localhost day06]# echo ${i}

[root@localhost day06]# i=100
[root@localhost day06]# ((i=i+1))
[root@localhost day06]# echo ${i}
101
[root@localhost day06]# 
6.1.4 $(())

$(())的操作,相当于 (()) + echo $变量名 的组合

格式

echo $((变量计算表达式))
注意:
	对于 $(())中间的表达式,可以不是一个整体,不受空格的限制

示例

[root@localhost day06]# echo ${i}

[root@localhost day06]# i=100
[root@localhost day06]# echo $((i=i+1))
101
[root@localhost day06]# 

6.2 expr 计算

expr即可以做常见的整数运算,还可以做数字比较,字符串计算等操作。

格式

数字场景:
	expr 运算表达式
字符串场景:
	match:用户获取匹配到字符串的长度
		expr match 字符串 匹配内容
	substr:截取字符串
		expr substr 字符串 起始位置 截取长度
		注意:起始位置值>=1
	index:查找第一次匹配字符的位置
		expr index 字符串 字符
	length:计算字符串的长度
		expr length 字符串 
6.2.1 match

获取用户 匹配到字符串的长度,如果某一个字符,在字符串中出现了很多次,以最后一次为准

[root@localhost day06]# name=gsfsfegdrgdfsfs
[root@localhost day06]# echo ${name}
gsfsfegdrgdfsfs
[root@localhost day06]# expr match $name ".*f"
14
[root@localhost day06]# 

6.2.2 substr

用来截取字符串,下标从1开始计算

[root@localhost day06]# echo ${name}
gsfsfegdrgdfsfs
[root@localhost day06]# expr substr $name 1 4
gsfs
[root@localhost day06]# 

6.2.3 index
[root@localhost day06]# echo ${name}
gsfsfegdrgdfsfs
[root@localhost day06]# expr index $name f
3
[root@localhost day06]# 

6.2.4 length
[root@localhost day06]# echo ${name}
gsfsfegdrgdfsfs
[root@localhost day06]# expr length $name
15
[root@localhost day06]# 

6.3 bc计算

bc是一种任意精度的计算语言,提供了语法结构,比如条件判断、循环等,功能是很强大的,还能进行进制转换。

格式

常见参数
    -i 强制交互模式;
    -l 使用bc的内置库,bc里有一些数学库,对三角计算等非常实用;
    -q 进入bc交互模式时不再输出版本等多余的信息。
特殊变量
    ibase,obase 用于进制转换,ibase是输入的进制,obase是输出的进制,默认是十进制;
    scale 小数保留位数,默认保留0位。

shell中实践

[root@localhost day06]# echo "scale=2; 9-1/7" | bc
8.86
[root@localhost day06]# echo "scale=1; 9-1/7" | bc
8.9
[root@localhost day06]# echo "9-1/7" | bc
9
[root@localhost day06]#

我们可以利用bc的一些API为我们做一些事情。只需要将内容通过管道符传递给bc 即可

6.4 测试表达式

格式

样式1: test 条件表达式
样式2: [ 条件表达式 ]
注意:
    以上两种方法的作用完全一样,后者为常用。
    但后者需要注意方括号[]与条件表达式之间至少有一个空格。
    test跟 [] 的意思一样
        条件成立,状态返回值是0
        条件不成立,状态返回值是1

示例

通过上述格式我们得知,测试表达式一般有两种格式,接下来让我们依次试试两种格式

通过test 来对表达式进行检验

[root@localhost day06]# test 1 == 1
[root@localhost day06]# echo $?
0
[root@localhost day06]# test 1 == 2
[root@localhost day06]# echo $?
1
[root@localhost day06]# echo $name
gsfsfegdrgdfsfs
[root@localhost day06]# test -v name
[root@localhost day06]# echo $?
0
[root@localhost day06]# unset name
[root@localhost day06]# test -v name
[root@localhost day06]# echo $?
1
[root@localhost day06]# 

通过符号[] 来对表达式进行校验

[root@localhost day06]# [ 1 == 1 ]
[root@localhost day06]# echo $?
0
[root@localhost day06]# [ 1 == 2 ]
[root@localhost day06]# echo $?
1
[root@localhost day06]# 

6.5 逻辑表达式

其实逻辑表达式无非是&&, ||, !. 废话不多说,我们来看几个实例

实例 1

下列 条件判断输出语句 是 && 关系。所以只有第一个满足的时候,才会执行第二个表达式

[root@localhost day06]# [ 1 == 1 ] && echo "1 == 1 满足,我就执行了"
1 == 1 满足,我就执行了

实例 2

下面的命令是由三个语句组成的,很显然第一个条件判断一定是不满足的,所以 && 不可能执行。只能执行 || 语句了

[ 1 == 2 ] && echo "1 == 1 满足,我就执行了" || echo "条件不满足,轮到我执行了"
条件不满足,轮到我执行了

实例 3

虽然第一个表达式不满足条件,但是结果取反了,所以执行了第二个表达式。

[ ! 1 == 2 ] && echo "1 == 2 不满足,但是我去反了,我就执行了"
1 == 2 不满足,但是我去反了,我就执行了

实例 4

判断参数个数,执行不同的逻辑

[root@localhost day06]# cat tshell002.sh 
#!/bin/bash

# 判断参数个数

args=$#

[ $args == 1 ] && echo "参数个数为1, 成功执行"
[ $args == 1 ] || echo "参数个数不为1, 失败执行"

实例 5

通过组合使用来判断目录是否存在

[root@localhost day06]# [ -d /etc ] && echo "/etc 目录存在" || echo "/etc 目录不存在"
/etc 目录存在
[root@localhost day06]# [ -d /etc1 ] && echo "/etc1 目录存在" || echo "/etc1 目录不存在"
/etc1 目录不存在
[root@localhost day06]# 

案例 6

通过shell 脚本检测服务器 活性

#!/bin/bash

# 表示ip检测

# 接受变量
_ip=$1
_ipN=$#


# ip非空判断
[ -z ${_ip} ] && echo "请输入检测IP" && exit
# 参数个数判断
[ ${_ipN} -ne 1 ] && echo "请保证输入一个脚本参数" && exit

# 执行命令
ping -c1 -w1 ${_ip} > /dev/null 2>&1

# 接受状态
status=$([ $? == 0 ] && echo "正常" || echo "异常")

echo "=============== 输出结果 ===================="
echo "您的IP<${_ip}>, 检测结果是: ${status}"
[root@localhost day06]# /bin/bash ./tshell003.sh 192.168.56.10
=============== 输出结果 ====================
您的IP<192.168.56.10>, 检测结果是: 正常

6.6 字符串表达式

  • == 判断两个字符串的内容是否一致
  • != 判断两个字符串的内容是否不一致
  • -z xxx 空值判断,如果字符串的长度为0,返回true
  • -n xxx 非空判断,如果字符串的长度不为0,返回true
  • -v xxx 空值判断,如果字符串的内容为空的话,返回true

6.7 文件表达式

文件属性判断

  • -d 检查文件是否存在且为目录文件
  • -f 检查文件是否存在且为普通文件
  • -S 检查文件是否存在且为socket文件
  • -L 检查文件是否存在且为链接文件
  • -O 检查文件是否存在并且被当前用户拥有
  • -G 检查文件是否存在并且默认组为当前用户组

文件权限判断

  • -x 检查文件是否存在 && 可执行
  • -w 检查文件是否存在 && 可写
  • -r 检查文件是否存在 && 可读

文件内容判断

  • -nt 检查file1是否比file2新
  • -ot 检查file1是否比file2旧
  • -ef 检查file1是否与file2是同一个文件,判定依据的是i节点

6.8 数字表达式

  • -eq 相等
  • -ne 不等于
  • -ge 大于等于
  • -gt 大于
  • -lt 小于
  • -le 小于等于

6.9 测试进阶表达式

我们可以将 [[ ]] 理解为增强版的 [ ],它不仅仅支持多表达式,还支持扩展正则表达式和通配符

格式

基本格式:
	[[ 源内容 操作符 匹配内容 ]]
	
操作符解析:
	== 左侧源内容可以被右侧表达式精确匹配
	=~ 左侧源内容可以被右侧表达式模糊匹配

实例

[root@localhost day06]# string=value
[root@localhost day06]# [[ $string == value ]]
[root@localhost day06]# echo $?
0
[root@localhost day06]# [[ $string == value1 ]]
[root@localhost day06]# echo $?
1
[root@localhost day06]# [[ $string == v* ]]
[root@localhost day06]# echo $?
0
[root@localhost day06]# [[ $string == v"*" ]]
[root@localhost day06]# echo $?
1
[root@localhost day06]# 

6.10 逻辑组合表达式

格式

方法1:
	[ 条件1 -a 条件2 ]		- 两个条件都为真,整体为真,否则为假
	[ 条件1 -o 条件2 ]		- 两个条件都为假,整体为假,否则为真
方法2:
	[[ 条件1 && 条件2 ]]	- 两个条件都为真,整体为真,否则为假
	[[ 条件1 || 条件2 ]]	- 两个条件都为假,整体为假,否则为真

实例

逻辑组合格式是限定的,如果使用符号[] ,内部判断必须使用-a. 使用符号[[]], 内部判断必须使用&&

[root@localhost day06]# account=root;pwd=123456
[root@localhost day06]# echo ${account} ${pwd}
root 123456
[root@localhost day06]# [ ${account} == "root" -a ${pwd} == "123456" ]
[root@localhost day06]# echo $?
0
[root@localhost day06]# [ ${account} == "roo1" -a ${pwd} == "123456" ]
[root@localhost day06]# echo $?
1
[root@localhost day06]# [ ${account} == "roo1" -o ${pwd} == "123456" ]
[root@localhost day06]# echo $?
0
[root@localhost day06]# [[ ${account} == "root" && ${pwd} == "123456" ]]
[root@localhost day06]# echo $?
0
[root@localhost day06]# [[ ${account} == "root1" || ${pwd} == "123456" ]]
[root@localhost day06]# echo $?
0
[root@localhost day06]# 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值