SHELL 脚本编程基础

Shell 语言是最精简的语言

什么是shell
我们将shell称作命令解释器(将命令转换成二进制语言,又将二进制语言转化成命令行)
shell不需要考虑效率,能实现功能就好

Linux支持的shell
主流shell:bash shell
[root@vm ~]#
[root@vm ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
[root@vm ~]#

1、echo命令
[root@vm ~]# echo 【选项】 【输出内容】
选项:
-e:支持反斜线控制的字符转换
-n:输出内容后不会换行

[root@vm ~]#
[root@vm ~]# echo -e "\a" #警告音

[root@vm ~]#
[root@vm ~]# echo -e "\ \a"
\
[root@vm ~]#
[root@vm ~]# echo -e "\" #\符号表示转义符,即把原来特殊字符的特殊意义去掉,让他变成一个普通的字符(如将具有特殊意义的美元$符号,变成一个普通的$符号)
\
[root@vm ~]#
[root@vm ~]# echo -e "1\t2"
1 2
[root@vm ~]#
[root@vm ~]# echo -e "ab\bc" #在这个输出中,在b侧右边有\b,在输出的时候,会向左将b删掉,所以只剩下了ac
ac
[root@vm ~]#
[root@vm ~]# echo -e "a\tb\tc\nd\te\tf"
a b c
d e f
[root@vm ~]#
[root@vm ~]# echo -e "\e[1;31m abcd \e[0m" #将abcd四个字母按照红色输出。解释一下这个命令 \e[1 是标准格式,代表颜色输出开始,\e[0m代表颜色输出结束。31m用来定义字符颜色是红色,echo能够识别的颜色如下:30m为黑色、31m为红色、32m为绿色、33m为黄色、34m为蓝色、35m为洋红色、36m为青色、37m为白色
abcd
[root@vm ~]#
[root@vm ~]# echo -e "\e[1;42m bcde \e[0m" #这条命令会给bcde四个字符加入一个绿色的背景,echo可以使用的背景颜色如下:40m为黑色、41m为红色、42m为绿色、43m为黄色、44m为蓝色、45m为洋红、46m为青色、47m为白色
bcde
[root@vm ~]#

2、脚本执行方法
[root@vm ~]# vim hello_world.sh #编写一个脚本
[root@vm ~]# cat hello_world.sh #查看脚本内容
#!/bin/bash
echo "hello world"
[root@vm ~]#
[root@vm ~]# sh hello_world.sh
hello world
[root@vm ~]#
[root@vm ~]# chmod +x hello_world.sh #赋予脚本可执行权限
[root@vm ~]# ll
-rwxr-xr-x 1 root root 32 Nov 16 22:07 hello_world.sh
[root@vm ~]#
[root@vm ~]# ./hello_world.sh #执行该脚本
hello world
[root@vm ~]#
[root@vm ~]# /root/hello_world.sh #通过绝对路径执行
hello world
[root@vm ~]#
[root@vm ~]# sh hello_world.sh #不需要可执行权限即可执行
hello world
[root@vm ~]#
[root@vm ~]# . hello_world.sh #不需要可执行权限即可执行
hello world
[root@vm ~]#
[root@vm ~]# bash hello_world.sh #不需要可执行权限即可执行
hello world
[root@vm ~]#

3、bash的基本功能
1)历史命令
按上下箭头可以翻出历史命令;
[root@vm ~]# history #在命令行执行history也可以查看执行过的历史命令
-c :清空历史命令(这个一般不推荐使用)
-w :执行这个命令可以在不正常退出Linux系统的情况下保存执行过的历史命令,如果不这样的话那就得用户注销才能实现该功能
[root@vm ~]# echo $HISTSIZE #系统默认保存1000条历史命令
1000
[root@vm ~]#

2).符号的意义
. 一个单独的点 表示source命令;
.bashrc 文件名前面加一个点表示隐藏文件
./ 目录前面加一个点表示该目录为当前目录
[root@vm ~]#
[root@vm ~]# cd ./ #切换到当前目录
[root@vm ~]# pwd #查看当前所在的位置
/root
[root@vm ~]#

3)bash常用快捷键

[root@vm ~]#
[root@vm ~]# abcdefghijklmnopqrstuvwxyz #敲这么一长串命令,此时我们可以看到光标在最右边

此时我们同时按住Ctrl+A键,然后发现光标竟然跑到命令最前面第一个字符的位置去了

此时我们同时按住Ctrl+E键,然后发现光标竟然跑到命令最后面的位置去了

此时我们同时按住Ctrl+U键,然后发现命令竟然全部消失了,使用Ctrl+U删除光标前的内容

此时我们同时按住Ctrl+Y键,然后发现命令竟然又全部恢复回来了,使用Ctrl+Y粘贴被Ctrl+U删掉的内容

此时我们同时按住Ctrl+K键,然后发现命令竟然又全部消失了,使用Ctrl+K删除光标后的内容

4)输入输出重定向
bash的标准输入输出

输出重定向
将命令的标准输出不再输出到屏幕上,而是将输出直接输出到文件里边,改变了输出方向,所以叫做输出重定向

[root@vm ~]#
[root@vm ~]# pwd > test.txt #标准正确输出(将正确的命令输出到文本中)
[root@vm ~]# cat test.txt
/root
[root@vm ~]#
[root@vm ~]# hjgfjjgfn > 1.txt #将一个错误的命令的执行结果输出到文本中的时候发现会报错
-bash: hjgfjjgfn: command not found
[root@vm ~]#
[root@vm ~]# hjgfjjgfn 2> 1.txt #只有在>号前面加一个2才会将标准错误输出到文本中
[root@vm ~]# cat 1.txt
-bash: hjgfjjgfn: command not found
[root@vm ~]#
[root@vm ~]# husigv > 2.txt 2>&1 #将标准错误输出到文本中将原文本覆盖掉
[root@vm ~]# cat 2.txt
-bash: husigv: command not found
[root@vm ~]#
[root@vm ~]# lkhjhhjsgvjk >> 2.txt 2>&1 #将标准错误输出到文本中在原文本后面进行追加
[root@vm ~]# cat 2.txt
-bash: husigv: command not found
-bash: lkhjhhjsgvjk: command not found
[root@vm ~]#

输入重定向
[root@vm ~]# wc 【选项】 【文件名】
-c:统计字节数
-w:统计单词数
-l:统计行数

5)多命令执行

案例:
使用 ;
[root@vm ~]#
[root@vm ~]# ls ; pwd #两条命令互不影响
hello_world.sh
/root
[root@vm ~]#
[root@vm ~]# lkhf ; ls
-bash: lkhf: command not found
hello_world.sh
[root@vm ~]#

使用&&
[root@vm ~]#
[root@vm ~]# ls && pwd
hello_world.sh
/root
[root@vm ~]#
[root@vm ~]# hlksg && pwd #两个条件同时满足才能执行
-bash: hlksg: command not found
[root@vm ~]#

使用 ||
[root@vm ~]#
[root@vm ~]# ls || pwd
hello_world.sh
[root@vm ~]# hjjlk || pwd #两个条件只有满足一个才执行,不能同时满足
-bash: hjjlk: command not found
/root
[root@vm ~]#

联合使用 && + ||
[root@vm ~]#
[root@vm ~]# pwd && echo true || echo false #判断命令是否正确
/root
true
[root@vm ~]#
[root@vm ~]# hgslk && echo true || echo false
-bash: hgslk: command not found
false
[root@vm ~]#

6)管道符 |
管道符:将前一个命令的输出结果作为后一个命令的输入
行提取命令grep

[root@vm ~]#
[root@vm ~]# cat /etc/passwd | grep root
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@vm ~]#

[root@vm ~]# netstat -an | grep ESTABLISHED #提取所有已经成功建立网络连接的行
tcp 0 0 172.30.16.85:39248 100.100.30.26:80 ESTABLISHED
tcp 0 36 172.30.16.85:22 223.104.39.67:2859 ESTABLISHED
[root@vm ~]#
[root@vm ~]# netstat -an | grep ESTABLISHED | wc -l #统计已经成功建立网络连接的行
2
[root@vm ~]#

7)通配符

8)bash中其他特殊符号

[root@vm ~]#
[root@vm ~]# name=zhangsan
[root@vm ~]# echo $name
zhangsan
[root@vm ~]# echo ‘$name‘ #美元符号在单引号中没有特殊意义
$name
[root@vm ~]# echo "$name" #美元符号在双引号中有特殊意义
zhangsan
[root@vm ~]#
[root@vm ~]# today=date #不加反引号的话,系统不知道date是一个命令
[root@vm ~]# echo $today
date
[root@vm ~]#
[root@vm ~]# today=date #加上反引号的话,系统就会把date当做一个命令来执行
[root@vm ~]# echo $today
Tue Nov 17 22:45:24 CST 2020
[root@vm ~]#

注意:
只有想把date这种类似的命令先运行,接着再把该命令的运行结果赋值给变量的时候,才需要给命令添加反引号;
在shell中推荐用 $() 来代替反引号,避免出错

[root@vm ~]# ls
hello_world.sh
[root@vm ~]#
[root@vm ~]# look=$(ls) #在Linux中 $() 和反引号的作用一模一样,而且可以避免看错
[root@vm ~]# echo $look #将ls看到的内容赋值给look变量
hello_world.sh
[root@vm ~]#

小括号和大括号的区别:

[root@vm ~]#
[root@vm ~]# (name=wangwu;echo $name) #在小括号中执行命令的时候其实是在子shell中执行,命令一旦执行完毕就会退出子shell,进入父shell中,所以在括号中打印出来的值和在括号外边打印出来的值是不一样的
wangwu
[root@vm ~]# echo $name
zhangsan
[root@vm ~]#
[root@vm ~]#
[root@vm ~]# { name=wangwu;echo $name; } #直接在父shell中执行,相当于不加括号一样
wangwu
[root@vm ~]# echo $name
wangwu
[root@vm ~]#

\ :转义符,将特殊符号的特殊意义给去掉,使特殊字符变成普通字符
[root@vm ~]#
[root@vm ~]# echo "$name"
wangwu
[root@vm ~]# echo "\$name"
$name
[root@vm ~]#

4、Bash的变量和运算符

1)变量的定义

[root@vm ~]#
[root@vm ~]# 1name=zhaoliu #变量不能以数字开头,否则会报错
-bash: 1name=zhaoliu: command not found
[root@vm ~]# name1=zhaoliu
[root@vm ~]#
[root@vm ~]# name = wangbadan #定义变量的时候,等号两边不能加空格
-bash: name: command not found
[root@vm ~]#

变量值是会覆盖的,最后一次命名的值会将原来命名的变量值覆盖掉
[root@vm ~]#
[root@vm ~]# name=1
[root@vm ~]# echo $name
1
[root@vm ~]# name=2
[root@vm ~]# echo $name
2
[root@vm ~]#
[root@vm ~]# num=123
[root@vm ~]# num="$num"456
[root@vm ~]# echo $num
123456
[root@vm ~]#

2)变量的分类

3)变量的查看
Set 【选项】
选项: -u
-u :如果设定了此选项,当调用未被声明的变量的时候会报错(默认是没有任何提示的)
[root@vm ~]#
[root@vm ~]# echo $hihi #在执行一个不存在的变量的时候,发现变量值输出总是为空

[root@vm ~]#
[root@vm ~]# set -u
[root@vm ~]# echo $hihi #当执行了 set -u 这个命令的时候,发现变量的输出值有显示了
-bash: hihi: unbound variable
[root@vm ~]#

4)变量的删除
unset 变量名
[root@vm ~]#
[root@vm ~]# name=zhangsan
[root@vm ~]# echo $name
zhangsan
[root@vm ~]# unset name
[root@vm ~]# echo $name
-bash: name: unbound variable
[root@vm ~]#

5)变量的比较
用户自定义变量只能在当前shell中执行;而用户自定义环境变量不仅可以在当前shell中执行,同时还可以在子shell中执行

6)环境变量

环境变量的设置(重点)
使用 export 声明的变量就是环境变量
[root@vm ~]#
[root@vm ~]# export age="25" #声明一个名为age的环境变量,变量值为25
[root@vm ~]# echo $age #查看环境变量的值
25
[root@vm ~]#

环境变量的查询和删除
env命令和set命令的区别是:set命令可以查看所有变量,而env命令只能查看环境变量
[root@vm ~]#
[root@vm ~]# name=wangwu #定义一个名为name的变量
[root@vm ~]# echo $name
wangwu
[root@vm ~]# unset name #删除这个变量
[root@vm ~]# env | grep name #查询这个变量是否还存在
[root@vm ~]#

PATH变量 (重点)
PATH变量为系统自带的环境变量
PATH变量的作用是指明系统查找文件的路径
[root@vm ~]#
[root@vm ~]# echo $PATH #查看PATH环境变量的值
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@vm ~]#
PATH变量的值是用“:”冒号分隔的路径,这些路径就是系统查找命令的路径,也就是说当我们输入了一个程序名,如果没有写入路径的话,系统就会到PATH变量定义的路径中去寻找,是否有可以执行的程序。如果找到的话就执行,否则会报“命令没有发现的错误”。

那么是不是我们把自己写的脚本拷贝到PATH变量定义的路径中,我们自己写的脚本文件也可以不用输入路径而直接运行呢?
[root@vm ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@vm ~]#
[root@vm ~]# ll #查看脚本是否具有可执行的权限
total 4
-rw-r--r-- 1 root root 32 Nov 16 22:07 hello_world.sh
[root@vm ~]#
[root@vm ~]# chmod +x hello_world.sh #赋予脚本可执行的权限
[root@vm ~]# cp ./hello_world.sh /usr/bin/ #将该脚本从当前目录拷贝至PATH变量所包含的目录中
[root@vm ~]# hello_world.sh #在不输入绝对路径的情况下直接执行该脚本程序,发现执行成功
hello world
[root@vm ~]#

那么我们是不是可以通过修改PATH变量的值,而不是把脚本程序复制到 /usr/bin 目录中,当然是可以的。我们只要通过变量的叠加就能实现
[root@vm ~]#
[root@vm ~]# rm -rf /usr/bin/hello_world.sh #先将原来拷贝到/usr/bin/目录下的脚本文件删除
[root@vm ~]# ls
hello_world.sh
[root@vm ~]#
[root@vm ~]# pwd #查看自己写的脚本所在的当前路径
/root
[root@vm ~]#
[root@vm ~]# PATH="$PATH":/root/ #将当前脚本所在的路径加入到PATH变量的值中,默认以冒号进行分隔
[root@vm ~]# echo $PATH #查看当前PATH环境变量的值
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/
[root@vm ~]#
[root@vm ~]# hello_world.sh #在没有做任何拷贝的情况下,直接执行自己编写的脚本,发现脚本执行成功
hello world
[root@vm ~]#

PS1变量:命令提示符变量

[root@vm ~]#
[root@vm ~]# echo $PS1 #查看PS1变量的值
[\u@\h \W]\$
[root@vm ~]#

LANG语系变量
LANG变量定义了Linux系统的主语系环境,这个变量的默认值是 en_US.UTF-8
[root@vm ~]# echo $LANG #默认为英文字符集
en_US.UTF-8
[root@vm ~]#
[root@vm ~]# locale -a | wc -l #目前 Linux 共支持789种语系
789
[root@vm ~]#
[root@vm ~]# locale #显示系统当前已经安装的语言程序
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
[root@vm ~]#

位置参数变量

[root@linux ~]#
[root@linux ~]# vi count.sh
[root@linux ~]# cat count.sh
#!/bin/bash

a=$1
b=$2

sum=$(( $a + $b ))

echo $sum

[root@linux ~]#
[root@linux ~]# chmod +x count.sh #赋予脚本可执行权限
[root@linux ~]# ./count.sh 22 33 #执行脚本,并将22和33这两个参数传递给$1和$2($1代表第一个参数,$2代表第二个参数,以此类推……)
55
[root@linux ~]#
[root@linux ~]# vi count.sh
[root@linux ~]# cat count.sh
#!/bin/bash

a=$1
b=$2

sum=$(( $a + $b ))

echo $sum

echo $0 #加入这行内容,在执行脚本

[root@linux ~]#
[root@linux ~]# ./count.sh 11 22 #写入脚本中$0,默认会输出执行命令本身
33
./count.sh
[root@linux ~]#
[root@linux ~]# vi para.sh
[root@linux ~]# cat para.sh
#!/bin/bash

echo "\$ is $"
echo "\$@ is $@"
echo "\$# is $#"

[root@linux ~]# chmod +x para.sh
[root@linux ~]# ./para.sh 11 22 33 #输入参数
$ is 11 22 33
$@ is 11 22 33
$# is 3
[root@linux ~]#
[root@linux ~]# ./para.sh 1 2 3 4
$
is 1 2 3 4
$@ is 1 2 3 4
$# is 4
[root@linux ~]#
[root@linux ~]#
[root@linux ~]# vi for.sh
[root@linux ~]# cat for.sh #在in后面有几个参数,就会循环几次,第一次将1赋给i,第二次将2赋给i,第三次将3赋给i
#!/bin/bash

for i in 1 2 3
do
echo $i
done

[root@linux ~]#
[root@linux ~]# chmod +x for.sh #赋予可执行权限
[root@linux ~]# ./for.sh #执行脚本,输出内容
1
2
3
[root@linux ~]#
[root@linux ~]# vi para2.sh
[root@linux ~]# cat para2.sh
#!/bin/bash

for I in "$*"
do
echo $i
done

echo ----------------------

for x in "$@"
do
echo $x
done

[root@linux ~]# chmod +x para2.sh
[root@linux ~]# ./para2.sh 11 22 33 #输入3个参数并执行脚本,可得知$与$@的区别(第一个循环只循环了一次,因为不论你有几个参数,在$看来都只是一个整体,所以只会循环一次;第二个循环循环了4次,因为$@会把每个参数都区别对待,有4个参数所以就会循环4次。
11 22 33

11
22
33
[root@linux ~]#

预定义变量

[root@linux ~]#
[root@linux ~]# pwd
/root
[root@linux ~]# echo $? #查看上一条命令是否执行成功
0
[root@linux ~]#
[root@linux ~]# jkkhlgas
-bash: jkkhlgas: command not found
[root@linux ~]# echo $? #只要是命令执行失败的话,$?的返回值就为非0的数
127
[root@linux ~]#
[root@linux ~]#
[root@linux ~]# echo $$ #输出当前进程的进程ID号
1151
[root@linux ~]#
[root@linux ~]# echo $! #输出后台运行的最后一个进程的进程id号

[root@linux ~]#

5、接收键盘输入

[root@linux ~]#
[root@linux ~]# vi read.sh
[root@linux ~]# cat read.sh
#!/bin/bash

read -t 30 -p "please input a num1: " num1
read -t 30 -p "please input a num2: " num2

sum=$(( $num1 + $num2 ))

echo $sum

[root@linux ~]# chmod +x read.sh #赋予脚本可执行权限
[root@linux ~]# ./read.sh #执行脚本
please input a num1: 1
please input a num2: 2
3
[root@linux ~]#
[root@linux ~]# ./read.sh
please input a num1: 10
please input a num2: 20
30
[root@linux ~]#

6、shell 的运算符
1)数值运算的方法
如果我们需要进行数值运算,可以采用以下3种方法中的任意一种:
使用declare 声明变量类型
既然所有变量的默认类型是字符串型,那么只要我们把变量声明为整数型不就可以运算了吗?使用declare命令就可以实现声明变量的类型。 命令如下:

[root@centos ~]#
[root@centos ~]# a=1 #定义变量a
[root@centos ~]# b=2 #定义变量b
[root@centos ~]# c=$a+$b #定义变量c等于$a+$b 的值
[root@centos ~]# echo $c #直接查看变量c的值,结果发现查看失败(因为在shell中,所有的变量类型都为字符型,不会把它当成数值型)
1+2
[root@centos ~]#
[root@centos ~]# declare -i c=$a+$b 使用declare将变量 c 指定为数值型变量
[root@centos ~]# echo $c #查看变量c的值
3
[root@centos ~]#

2)数组变量类型

[root@centos ~]#
[root@centos ~]# name[0]="zhangsan" #定义数组name中第一个变量0的值为张三
[root@centos ~]# name[1]="wangwu" #定义数组name中第一个变量0的值为王五
[root@centos ~]# name[2]="maqi" #定义数组name中第一个变量0的值为马七
[root@centos ~]# echo ${name[*]} #查看数组中各个变量的值
zhangsan wangwu maqi
[root@centos ~]#

3)环境变量
我们其实也可以使用declare命令把变量声明为环境变量,和export命令的作用是一样的
[root@centos ~]#
[root@centos ~]# declare -x test=123 #使用declare命令将test定义为环境变量
[root@centos ~]# echo $test #查看test环境变量的值
123
[root@centos ~]#

4)只读属性
注意一旦给变量设置了只读属性,那么这个变量既不能修改变量的值,也不能删除变量,甚至不能使用“+r”选项取消只读属性,命令如下:
[root@centos ~]#
[root@centos ~]# declare -r test #将test变量赋予只读属性
[root@centos ~]# declare -p #查看变量
declare -rx test="123"
[root@centos ~]#
[root@centos ~]# unset test #此时尝试删除test变量,发现报错没有办法删除
-bash: unset: test: cannot unset: readonly variable
[root@centos ~]#
[root@centos ~]# test=456 #尝试将test变量的值更改为456,结果显示只有只读权限,无权做修改
-bash: test: readonly variable
[root@centos ~]#

5)查询变量属性和取消变量属性
变量属性的查询使用“-p”选项,变量属性的取消使用“+”选项。命令如下:
[root@centos ~]#
[root@centos ~]# declare -p #查询所有变量

6)使用expr或let数值运算工具
要想进行数值运算的第二种方法是使用expr命令,这种命令就没有declare复杂了
[root@centos ~]#
[root@centos ~]# a=11 #定义变量a为11
[root@centos ~]# b=22 #定义变量b为22
[root@centos ~]# c=$(expr $a + $b) #定义变量c的值为$(expr $a + $b)
[root@centos ~]# echo $c #查看变量c的值
33
[root@centos ~]#
[root@centos ~]# let d=$a+$b #使用let命令定义一个变量
[root@centos ~]# echo $d #查看变量d的值
33
[root@centos ~]#

7)使用"$((运算式))" 或 “[运算式]”方式运算
生产环境推荐使用 $((运算式)) 这种运算
其实这是一种方式"$(())"和"$[]" 这两种括号按照个人习惯使用即可
[root@centos ~]#
[root@centos ~]# a=22
[root@centos ~]# b=33
[root@centos ~]# c=$(( $a+$b )) #定义一个变量c等于$a+$b 的值
[root@centos ~]# echo $c #查看变量$c的值
55
[root@centos ~]#

8)shell的常用运算符

7、四则运算练习
[root@centos ~]#
[root@centos ~]# vi count4.sh #编写脚本
[root@centos ~]# cat count4.sh #查看脚本内容
#!/bin/bash

read -t 30 -p "please input num1: " num1
read -t 30 -p "please input num1: " num2
read -n1 -t 30 -p "please input operato[+-/]: " oper
echo -e "\n"
[ "$oper" == "+" ] && echo "$(( $num1 + $num2 ))"
[ "$oper" == "-" ] && echo "$(( $num1 - $num2 ))"
[ "$oper" == "
" ] && echo "$(( $num1 * $num2 ))"
[ "$oper" == "/" ] && echo "$(( $num1 / $num2 ))"

[root@centos ~]# chmod +x count4.sh #赋予脚本可执行权限
[root@centos ~]# ./count4.sh #执行脚本
please input num1: 22 #输入数字
please input num1: 33 #输入数字
please input operato[+-*/]: + #输入运算符

55
[root@centos ~]#
[root@centos ~]# vi count4.sh #修改一下脚本内容
[root@centos ~]# cat count4.sh #查看脚本内容
#!/bin/bash

read -t 30 -p "please input num1: " num1
read -t 30 -p "please input num1: " num2
read -n1 -t 30 -p "please input operato[+-/]: " oper
echo -e "\n"
[ "$oper" == "+" ] && echo "$(( $num1 + $num2 ))" && exit
[ "$oper" == "-" ] && echo "$(( $num1 - $num2 ))" && exit
[ "$oper" == "
" ] && echo "$(( $num1 * $num2 ))" && exit
[ "$oper" == "/" ] && echo "$(( $num1 / $num2 ))" && exit

echo "请输入正确运算符"
[root@centos ~]#
[root@centos ~]# ./count4.sh #执行一次正确的运算脚本
please input num1: 11
please input num1: 22
please input operato[+-/]:

242
[root@centos ~]#
[root@centos ~]# ./count4.sh #执行一次错误的运算脚本,对比效果
please input num1: 55
please input num1: 22
please input operato[+-*/]: c

请输入正确运算符
[root@centos ~]#

8、变量的测试与内容置换

[root@centos ~]#
[root@centos ~]# y=""
[root@centos ~]# x=${y-new}
[root@centos ~]# echo $x

[root@centos ~]#
[root@centos ~]# y=1 #当y为1的时候
[root@centos ~]# x=${y-new}
[root@centos ~]# echo $x #查看x的值
1
[root@centos ~]#

9、环境变量配置文件【重点内容】
1)source 命令
source 配置文件
或者
. 配置文件

2)环境变量配置文件
登录时生效的环境变量配置文件
在Linux系统登录时主要生效的环境变量配置文件有以下5个(按照生效顺序排列):
/etc/profile #对所有用户都生效
/etc/profile.d/*.sh #对所有用户都生效
~/.bash_profile #只对当前用户生效
~/.bashrc #只对当前用户生效
/etc/bashrc #对所有用户都生效

在用户登陆过程先调用 /etc/profile 文件:

由/etc/profile文件调用/etc/profile.d/*.sh文件:

由/etc/profile文件调用~/.bash_profile文件:

由~/.bash_profile文件调用~/.bashrc文件

由~/.bashrc文件调用了/etc/bashrc文件:

3)在注销时生效的环境变量配置文件

4)其它配置文件
还有一些环境变量配置文件,最常见的就是~/.bash_history文件,也就是历史命令保存文件。

10、shell 登录信息
/etc/issue

可以支持的转义符我们可以通过 man agetty 命令查询,在下表中我们列出常见的转义符作用:

11、定义bash快捷键
[root@centos ~]#
[root@centos ~]# stty -a #查询所有的快捷键
speed 38400 baud; rows 35; columns 191; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O;
min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
[root@centos ~]#

SHELL 脚本编程基础

SHELL 脚本编程基础

上一篇:shell脚本基本命令1


下一篇:linux定时任务crond那些事!