1.加export和不加的区别

在Shell脚本中,`export`命令用于将变量导出为环境变量,使其在脚本之外也可被其他程序或子进程访问。不带`export`的变量仅在当前Shell脚本的作用域中可见。

区别如下:

变量作用范围:使用`export`命令导出的变量可以被当前Shell脚本以及子进程或其他程序访问,而不带`export`的变量仅在当前Shell脚本内部可见。

子进程访问:使用`export`导出的变量可以在当前Shell脚本的子进程中访问,而不带`export`的变量不可在子进程中访问。

环境变量:使用`export`导出的变量将成为环境变量,可以被其他程序或Shell脚本访问。而不带`export`的变量不会成为环境变量。

总之,使用`export`命令可以将变量导出为环境变量,使其在脚本之外的范围也可被访问和使用。不带`export`的变量则仅在当前Shell脚本的作用域内可见

环境变量初始化与对应文件的生效顺序

用户登录系统后首先会加载/etc/profile全局环境变量文件,加载完后,执行/etc/profile.d目录下的脚本文件(如:系统的字符集设置/etc/sysconfigil8n),然后在运行$HOME/.bash_profile(用户环境变量文件),在这文件里会找$HOME/.bashrc(用户环境变量文件),有就执行,没有就不执行。在$HOME/.bashrc找/etc/bashrc(全局环境变量文件)有就执行,没有就不执行。如果希望用户的Shell不是登陆时启动的(如:手动敲下bash时启动或者远程ssh连接情况),非登陆Shell只会加载$HOME/.bashrc(用户环境变量文件),并会去找/etc/bashrc(全局环境变量文件)。即非登陆Shell想读到设置的环境变量,需要将变量设定等写入$HOME/.bashrc(用户环境变量文件)或etc/bashrc(全局环境变量文件)不是$HOME/.bash_profile或/etc/profile。。。

2.变量值的定义

变量名=value       #不加引号时,值里有变量的会被解析后输出。

变量名=’value’     #输出变量内容时单引号里是什么就输出什么,不管什么都原样输出。

变量名=”value”    #输出变量内容时引号里的变量和命令经过解析后输出。

命令结果作为的变量内容来赋值

变量名=`mkdir`    #这里是反引号,

变量名=$(mkdir)  #把命令$()括起来,来赋值。

单引号:所见即所得,吃啥吐啥,原封不动的输出。
双引号:与单引号类似,特殊符号会被解析(运行):() “
不加引号:与双引号类似,如果出现空格,不会算作一个整体。
反引号:先执行反引号里面的命令,把执行的结果显示出来。

3.查看环境变量

set命令输出所有的变量,包括全局变量和局部变量

[root@shell01 ~]$ set

APACHEERR=hello world
BASH=/bin/bash
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="1" 
#中间和结尾省略若干代码

env(printenv)命令只显示全局变量

[root@shell01 ~]$ env
XDG_SESSION_ID=10
HOSTNAME=shell01
TERM=linux
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=10.0.0.1 8593 22
SSH_TTY=/dev/pts/0
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
LANG=en_US.UTF-8
PS1=[\[\e[34;1m\]\u@\[\e[0m\]\[\e[32;1m\]\H\[\e[0m\] \[\e[31;1m\]\w\[\e[0m\]]\\$ 
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
SSH_CONNECTION=10.0.0.1 8593 10.0.0.65 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env

查看设置的变量

添加

[root@shell01 ~]$ name=hostname
[root@shell01 ~]$ echo $name
hostname

set可以设置某个环境变量的值。清除环境变量的值用unset命令。如果未指定值,则该变量值将被设为NULL

删除

[root@shell01 ~]$ echo $name
hostname
[root@shell01 ~]$ uns
unset unshare
[root@shell01 ~]$ unset name
[root@shell01 ~]$ echo $name

4.Shell 脚本中 ‘$’ 符号的多种用法

$0:Shell 的命令本身1 到1 到9:表示 Shell 的第几个参数
$n:表示脚本的第n个参数 n为数字 0已经被脚本名称占用 从1开始 从$9后 需要加花括号引起来作为一个整体${10}
$?:显示最后命令的执行情况,0为成功 非0失败 返回值0-255 可以自定义返回值
$#:传递到脚本的参数个数
$$:脚本运行的当前进程 ID(PID) 号
$*:以一个单字符串显示所有向脚本传递的参数,表示传参的所有参数 不加双引号和$@:相同 加上双引号 表示为一个参数 在脚本中相同 循环体不同
$!:后台运行的最后一个进程的 ID 号
$-:显示 Shell 使用的当前选项
$_:表示上一个命令的最后一个参数。通常用于快速重复上一个命令的最后一个参数

5.shell-变量输入内置read命令详解

-p:给提示语
-s:隐藏用户输入的信息
-t:设置超时时间(s)
-a:后跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分割符。
-n:指定字符个数

把加减乘除计算的脚本改成通过read方式读入整数变量

[root@shell01 /server/scripts]$ cat jiajian.sh
#!/bin/bash
a=$1
b=$2

echo “a-b=$(( $a – $b ))”
echo “a+b=$(( $a + $b ))”
echo “a*b=$(( $a * $b ))”
echo “a/b=$(( $a / $b ))”
echo “a**b=$(( $a ** $b ))”
echo “a%b=$(( $a %$b ))”
[root@shell01 /server/scripts]$ sh jiajian.sh 9 6
a-b=3
a+b=15
a*b=54
a/b=1
a**b=531441
a%b=3

修改成read

[root@shell01 /server/scripts]$ cat jiajian01.sh
#!/bin/bash
read -p “请输入数字: ” a b

echo “a-b=$(( $a – $b ))”
echo “a+b=$(( $a + $b ))”
echo “a*b=$(( $a * $b ))”
echo “a/b=$(( $a / $b ))”
echo “a**b=$(( $a ** $b ))”
echo “a%b=$(( $a %$b ))”
[root@shell01 /server/scripts]$ sh jiajian01.sh
请输入数字: 9 3
a-b=6
a+b=12
a*b=27
a/b=3
a**b=729
a%b=0

read修改主机名称和IP地址

[root@shell01 /server/scripts]$ cat hostname.sh
#!/bin/sh
IP_DIR=/etc/sysconfig/network-scripts/ifcfg-eth0
S_IP=`hostname -I|awk ‘{print $1}’`
read -p “请输入你要修改的主机名称: ” name
hostnamectl set-hostname $name

read -p “请输入你要修改的IP地址: ” D_IP
sed -i “s#$S_IP#10.0.0.$D_IP#g” $IP_DIR
grep IPADDR $IP_DIR

6.变量的子串

(空格需要算一个字符)

表达式 说明
${parameter} 返回变量$parameter的内容
${#parameter} 返回变量$parameter内容的长度(按字符),也适用于特殊变量
${parameter:offset} 在变量${parameter}中,从位置offset之后开始提取子串到结尾
${parameter:offset:length} 在变量${parameter}中,从位置offset之后开始提取长度为length的子串
${parameter#word} 从变量${parameter}开头开始删除最短匹配的word子串
${parameter##word} 从变量${parameter}开头开始删除最长匹配的word子串
${parameter%word} 从变量${parameter}结尾开始删除最短匹配的word子串
${parameter%%word} 从变量${parameter}结尾开始删除最长匹配的word子串
${parameter/pattern/string} 使用string代替第一个匹配的pattern
${parameter//pattern/string} 使用string代替所有匹配的pattern

取变量的长度

[root@shell ~]$ sentence=’go up to heaven and enter the earth’
[root@shell ~]$ echo $sentence
go up to heaven and enter the earth

[root@shell ~]$ echo $sentence | wc -L
35

[root@shell ~]$ expr length “$sentence”
35

[root@shell ~]$ echo $sentence|awk ‘{print length($0)}’
35

[root@shell ~]$ echo ${#sentence}
35

截取变量的内容

[root@shell ~]$ echo $sentence
go up to heaven and enter the earth

从第2个字符之后开始截取,默认截取后面字符的全部,第2个字符不包含在内,也可理解为删除前面的多个字符

[root@shell ~]$ echo ${sentence:2}
up to heaven and enter the earth

截取变量的内容,从第3个字符之后开始截取,截取2个字符

[root@shell ~]$ echo ${sentence:3:2}
up

统计出变量中的长度小于3的值

[root@shell ~]$ echo $sentence |awk ‘{for(i=1;i<=NF;i++)if(length($i)<3)print $i}’
go
up
to

[root@shell ~]$ echo $sentence|xargs -n1|awk ‘{if(length<3)print}’
go
up
to

[root@shell /server/scripts]$ cat for.sh
for i in go up to heaven and enter the earth
do
[ ${#i} -lt 3 ] && echo $i
done
[root@shell /server/scripts]$ sh for.sh
go
up
to

删除

[root@shell /server/scripts]$ url=www.feitian.com
[root@shell /server/scripts]$ echo $url
www.feitian.com

从前面往后删除 可以使用通配符匹配字符串

[root@shell /server/scripts]$ echo ${url#*.}
feitian.com

删除到最后一个

[root@shell /server/scripts]$ echo ${url##*.}
com
[root@shell /server/scripts]$ echo ${url#*.*.}
com

从后往前删除

[root@shell /server/scripts]$ echo ${url%.*.*}
www

[root@shell /server/scripts]$ echo ${url%%.*}
www

[root@shell /server/scripts]$ num=100%
[root@shell /server/scripts]$ echo $num
100%
[root@shell /server/scripts]$ echo ${num%\%}
100

#表示从开头删除匹配最短。
##表示从开头删除匹配最长。
%表示从结尾删除匹配最短。
%%表示从结尾删除匹配最长。
a*c表示匹配的字符串,*表示匹配所有,a*c匹配开头为a、中间为任意多个字符、结尾为c的字符串。
a*C表示匹配的字符串,*表示匹配所有,a*C匹配开头为a、中间为任意多个字符、结尾为C的字符串。

替换

[root@shell /server/scripts]$ url=www.feitian.com
[root@shell /server/scripts]$ echo $URL
www.feitian.com

[root@shell /server/scripts]$ echo ${url/www/test}
test.feitian.com

[root@shell /server/scripts]$ echo ${url/w/W}
Www.feitian.com

[root@shell /server/scripts]$ echo ${url//w/W}
WWW.feitian.com

[root@shell /server/scripts]$ echo ${url/m/W}
www.feitian.coW

7.数值运算

i++ 和 ++i 的区别

赋值顺序不同,++i是先加后赋值;i++是先赋值后加;++i和i++都是分两步完成的。

效率不同,比如i=3,b=i++就是说b=3,完成之后让i变成4,b=++i就是先让i++变成4,然后b=4,其中++i比i++效率要高些。一般来说在循环域里面,这两者并没有什么很大的区别,但是要注意其生存周期,以及i值在程序流中的变化。

i++不能作为左值,而++i可以。左值是对应内存中有确定存储地址的对象的表达式的值,而右值是所有不是左值的表达式的值。一般来说,左值是可以放到赋值符号左边的变量。

i++和++i都是实现变量i的自增,两者的区别在于i++是先运算,再加1,而++i是先加1,后运算。但是不管是i++还是++i,最后i的值都是相同的。5、操作结果不同,对于n=++i,进行操作后,n的值发生了改变,其值变成了i+1,对于n=i++,进行操作后,n的值不发生改变,其值仍然为i。

expr只支持整数运算

加减乘除

[root@shell /server/scripts]$ expr 10 + 1
11
[root@shell /server/scripts]$ expr 10 – 1
9
[root@shell /server/scripts]$ expr 10 \* 3
30
[root@shell /server/scripts]$ expr 10 / 2
5

判断我们输入的数字是否为整数

[root@shell /server/scripts]$ cat num.sh
#!/bin/sh
read -p “请输入一个整数: ” num
expr 1 + $num &>/dev/null
[ $? -ne 0 ] && echo “你输入的不是整数” && exit

echo $num

$[] 是一种旧式的整数运算语法,通常用于进行算术运算

[root@shell /server/scripts]$ echo $[1+10]
11
[root@shell /server/scripts]$ echo $[1*10]
10
[root@shell /server/scripts]$ echo $[1-10]
-9
[root@shell /server/scripts]$ echo $[10-2+5]
13
[root@shell /server/scripts]$ echo $[2**2]
4
[root@shell /server/scripts]$ echo $[2^2]
0
[root@shell /server/scripts]$ echo $[2/2]

$(())注意两个小括号是做运算 一个小括号是执行命令 $() 运算效率最高

[root@shell /server/scripts]$ echo $((10+2-5))
7
[root@shell /server/scripts]$ echo $((10+2*5))
20
[root@shell /server/scripts]$ echo $(((10+2)*5))
60
[root@shell /server/scripts]$ echo $(((10+2)/6))
2

let运算需要使用变量只支持整数运算

let 是用于执行算术运算的内置命令。它允许你在Shell脚本中进行整数运算,并将结果赋值给变量。

加法

let result=5+3
echo $result  
输出:8

减法

let result=5-3
echo $result  
输出:2

乘法

let result=5*3
echo $result  
输出:15

除法

let result=10/2
echo $result  
输出:5

与$[]、$(())和expr命令不同,let命令不需要对乘法符号*进行转义。另外,它也只支持整数运算,无法处理浮点数。

bc 是一个用于数学运算的命令行工具,它支持整数和浮点数的运算,以及各种数学函数和表达式。

整数运算

[root@shell /server/scripts]$ echo "5 + 3" | bc
8
[root@shell /server/scripts]$ echo 5 + 3 | bc
8

浮点数运算

[root@shell /server/scripts]$ echo "5.5 * 2.2" | bc
12.1

使用变量

x=5
y=3
echo "$x + $y" | bc  
输出:8

使用数学函数

echo "s(0)" | bc -l  
输出:0.00000000000000000000

在上面的例子中,-l 选项用于加载标准数学库,以便可以使用数学函数。

bc 是一个功能强大的命令行工具,可以用于处理复杂的数学计算。但需要注意的是,在处理浮点数时,bc 可能会产生一些精度问题。

awk运算

[root@shell /server/scripts]$ awk ‘BEGIN{print 10+10}’
20
[root@shell /server/scripts]$ awk ‘BEGIN{print 10-10}’
0
[root@shell /server/scripts]$ awk ‘BEGIN{print 10+100/2}’
60
[root@shell /server/scripts]$ awk ‘BEGIN{print 10+100/2*4}’
210

[root@shell /server/scripts]$ echo 10 20|awk ‘{print $1+$2}’
30

python 直接运算

[root@shell /server/scripts]$ python
Python 2.7.5 (default, Apr 2 2020, 13:16:51)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> 1+1
2
>>> 10*10
100
>>> 1.5*10
15.0
>>> 100/2.5
40.0
>>> 10+10*10/2
60

表示符

-eq:等于

-ne:不等于

-lt:小于

-le:小于等于

-gt:大于

-ge:大于等于

在Shell脚本中,常用的逻辑运算符包括以下几种:

逻辑与:&&

用法:command1 && command2

解释:表示当 command1 执行成功(返回状态码为0)时,才会执行 command2。

逻辑或:||

用法:command1 || command2

解释:表示当 command1 执行失败(返回状态码非0)时,才会执行 command2。

逻辑非:!

用法:!command

解释:表示对 command 的执行结果进行取反,即如果 command 执行成功,则返回状态码为0,否则返回状态码非0

在Shell中,or 和 and 也可以使用 -o 和 -a 来表示。这些都是逻辑运算符,用于在条件语句中连接多个条件。

-o 表示逻辑或,它连接的两个条件中只要有一个为真,整个条件就为真。例如:

if [ "$a" -eq 1 -o "$b" -eq 2 ]
then
  echo "a is 1 or b is 2"
fi

上面的代码中,如果 $a 的值等于 1 或者 $b 的值等于 2,那么整个条件就会为真,执行 echo 语句。

-a 表示逻辑与,它连接的两个条件都必须为真,整个条件才为真。例如:

if [ "$a" -eq 1 -a "$b" -eq 2 ]
then
  echo "a is 1 and b is 2"
fi

上面的代码中,如果 $a 的值等于 1 且 $b 的值等于 2,那么整个条件就会为真,执行 echo 语句。

需要注意的是,-o 和 -a 的优先级比较低,因此在使用时需要加上括号,以确保条件的优先级正确。例如:

if [ "$a" -eq 1 -o "$b" -eq 2 ] && [ "$c" -eq 3 ]
then
  echo "a is 1 or b is 2, and c is 3"
fi

上面的代码中,-o 的优先级比 -a 低,因此需要加上括号,以确保先执行 -o 连接的两个条件,再执行 -a 连接的条件。

通配符用于匹配文件名或路径名中的字符。常用的通配符包括以下几种:

*:匹配零个或多个任意字符。

例如:*.txt 可以匹配所有以 .txt 结尾的文件名。

?:匹配单个任意字符。

例如:file?.txt 可以匹配 file1.txt、file2.txt 等。

[]:匹配指定范围内的字符。

例如:[abc] 可以匹配单个字符为 a、b 或 c 的文件名。

{}:用于生成字符串序列。

例如:{apple,banana,orange} 可以匹配 apple、banana 或 orange。

这些通配符可以在Shell中用于文件名的匹配和替换,帮助我们进行文件操作和批量处理。

test

文件属性测试

-e file:检查文件是否存在
-f file:检查文件是否存在且为常规文件
-d file:检查文件是否存在且为目录
-r file:检查文件是否存在且可读
-w file:检查文件是否存在且可写
-x file:检查文件是否存在且可执行
-s file:检查文件是否存在且非空
-O file:检查当前用户是否是文件的所有者
-G file:检查文件的所属组是否与当前用户相同
file1 -nt file2:检查 file1 是否比 file2 新
file1 -ot file2:检查 file1 是否比 file2 旧

字符串比较

-z string:检查字符串是否为空
-n string:检查字符串是否非空
string1 = string2:检查两个字符串是否相等
string1 != string2:检查两个字符串是否不相等

数值比较

int1 -eq int2:检查两个整数是否相等
int1 -ne int2:检查两个整数是否不相等
int1 -gt int2:检查 int1 是否大于 int2
int1 -ge int2:检查 int1 是否大于等于 int2
int1 -lt int2:检查 int1 是否小于 int2
int1 -le int2:检查 int1 是否小于等于 int2

这些参数可以用于在 Shell 脚本中进行条件测试。例如:

if [ -f “$file” -a -r “$file” ];
then echo “文件 $file 存在且可读”
fi

上面的代码中,-f “$file” 用于检查文件是否存在且为常规文件,-r “$file” 用于检查文件是否存在且可读。如果这两个条件都满足,则打印出文件存在且可读的信息。

test的使用

[root@shell /server/scripts]$ test 10 -eq 10 && echo 成立 || echo 不成立
成立
[root@shell /server/scripts]$ test 100 -eq 10 && echo 成立 || echo 不成立
不成立
[root@shell /server/scripts]$ test 100 -ne 10 && echo 成立 || echo 不成立
成立

比较大小

[root@shell /server/scripts]$ [ 10 -gt 5 ] && echo 成立 || echo 不成立
成立
[root@shell /server/scripts]$ [ 10 -ne 5 ] && echo 成立 || echo 不成立
成立
[root@shell /server/scripts]$ [ 10 -lt 5 ] && echo 成立 || echo 不成立
不成立
[root@shell /server/scripts]$ [ 10 -gt 10 ] && echo 成立 || echo 不成立
不成立
[root@shell /server/scripts]$ [ 10 -ge 10 ] && echo 成立 || echo 不成立
成立

判断传入的参数必须为整数 否则退出脚本

[root@shell /server/scripts]$ cat count.sh
#!/bin/bash
echo $1+$2=$[$1+$2]
echo $1-$2=$[$1-$2]
echo $1*$2=$[$1*$2]
echo $1/$2=$[$1/$2]
echo “——————————-”
num1=$1
num2=$2
#echo $num1+$num2=$[$num1+$num2]
#echo $num1-$num2=$[$num1-$num2]
#echo $num1*$num2=$[$num1*$num2]
#echo $num1/$num2=$[$num1/$num2]
read -p “请输入两个整数: ” num1 num2
expr $num1 + $num2 &>/dev/null
[ $? -ne 0 ] && echo “你输入的不是整数” && exit
echo $num1+$num2=$[$num1+$num2]
echo $num1-$num2=$[$num1-$num2]
echo $num1*$num2=$[$num1*$num2]
echo $num1/$num2=$[$num1/$num2]
[root@shell /server/scripts]$ sh count.sh 10 20
10+20=30
10-20=-10
10*20=200
10/20=0
——————————-
10+20=30
10-20=-10
10*20=200
10/20=0
请输入两个整数: 10 20
10+20=30
10-20=-10
10*20=200
10/20=0

循环(正确则退出,错误则继续)

[root@shell /server/scripts]$ cat count1.sh
#!/bin/bash
echo $1+$2=$[$1+$2]
echo $1-$2=$[$1-$2]
echo $1*$2=$[$1*$2]
echo $1/$2=$[$1/$2]
echo “——————————-”
num1=$1
num2=$2
echo $num1+$num2=$[$num1+$num2]
echo $num1-$num2=$[$num1-$num2]
echo $num1*$num2=$[$num1*$num2]
echo $num1/$num2=$[$num1/$num2]
while true
do
read -p “请输入两个整数: ” num1 num2
expr $num1 + $num2 &>/dev/null
[ $? -ne 0 ] && echo “你输入的不是整数” && continue
echo $num1+$num2=$[$num1+$num2]
echo $num1-$num2=$[$num1-$num2]
echo $num1*$num2=$[$num1*$num2]
echo $num1/$num2=$[$num1/$num2]
break

done
[root@shell /server/scripts]$ sh count1.sh 10 20
10+20=30
10-20=-10
10*20=200
10/20=0
——————————-
10+20=30
10-20=-10
10*20=200
10/20=0
请输入两个整数: 12 12.1
你输入的不是整数
请输入两个整数: 12 12
12+12=24
12-12=0
12*12=144
12/12=1

第二种

[root@shell /server/scripts]$ cat count2.sh
#!/bin/bash
read -p “请输入第一个整数:” a
read -p “请输入加减乘除或其他运算符号:” c
read -p “请输入第二个整数:” b
expr $a + $b &>/dev/null
if [ $? -eq 0 ];then
d=$(awk ‘BEGIN{print ‘$a’ ‘$c’ ‘$b’}’)
echo “你要运算的是$a$c$b=$d”
else
echo “你输入的不是整数,或特殊字符未转义”
fi

统计内存使用率 使用率超过百分之5 则发送邮箱报警 否则输出提示使用正常 输出当前内存使用率
内存百分比计算方式: 已使用的除总的乘100

[root@shell /server/scripts]$ cat free.sh
#!/bin/sh
Mem_use=`free|awk ‘NR==2{print $3/$2*100}’`
[ ${Mem_use%.*} -gt 5 ] && echo -e “Subject: free\n\n${Mem_use%.*}” | sendmail -v xxxxxxxxx@163.com || echo ${Mem_use}%

#[ ${Mem_use%.*} -gt 5 ] && echo “${Mem_use%.*}” | mail -s “free” xxxxxxxx@163.com || echo ${Mem_use}%

统计1分钟内系统的平均负载 超过1则发送邮件 否则提示正常

[root@shell /server/scripts]$ cat upload.sh
#!/bin/sh
use_load=`uptime|awk ‘{print $(NF-2)}’`
[ ${use_load%.*} -gt 1 ] && echo -e “Subject: upload\n\n${use_load%.*}” | sendmail -v xxxxxxxxxx@163.com || echo “${use_load%,}%”

[root@shell ~]$ ulimit -HSn 65535

这条命令用于设置当前用户的最大文件描述符数量为65535。文件描述符是操作系统用来标识已被打开文件的一种方法。通过设置最大文件描述符数量,可以控制用户能够同时打开的文件数量。

具体而言,ulimit -HSn 65535中:

ulimit 是一个用于设置或显示用户进程资源限制的命令。
-H 表示设置或显示硬限制,即用户能够设置的最大值。
-S 表示设置或显示软限制,即用户当前实际可用的最大值。
n 表示文件描述符的数量。
65535 是设定的文件描述符数量。

这条命令的作用是将当前用户的软限制和硬限制都设置为65535,即用户可以同时打开的文件数量最大为65535。

[root@shell ~]$ ab -n200000 -c20000 http://127.0.0.1/index.html

[[ ]] 是 Bash shell 中的一种条件语句,用于测试条件是否成立。与单个方括号 [ ] 不同,[[ ]] 支持更多的条件测试和语法。

[[ expression ]]

其中 expression 是一个条件表达式,可以包含变量、字符串、数字、运算符等。[[ ]] 会将 expression 中的内容作为一个整体进行解析和判断,可以使用各种条件测试来判断其是否为真。

[[ ]] 支持的条件测试包括:

字符串比较:==、!=、=~(正则表达式匹配)

数值比较:-eq、-ne、-lt、-le、-gt、-ge

文件测试:-e(文件是否存在)、-f(是否为文件)、-d(是否为目录)、-r(是否可读)、-w(是否可写)、-x(是否可执行)

逻辑运算:&&(逻辑与)、||(逻辑或)、!(逻辑非)

[[ ]] 的优点是可以避免一些常见的问题,比如字符串中包含空格或特殊字符时的问题,以及各种条件测试的语法问题。因此,在 Bash shell 中,推荐使用 [[ ]] 来进行条件判断。

[[]]的使用

检查变量是否为空:

if [[ -z $var ]]; then
    echo "变量 var 为空"
fi

字符串比较:

if [[ $str1 == $str2 ]]; then
    echo "str1 和 str2 相等"
fi

文件属性检查:

if [[ -f $file && -r $file ]]; then
    echo "文件 $file 存在且可读"
fi

数值比较:

if [[ $num -gt 10 ]]; then
    echo "num 大于 10"
fi

正则表达式匹配:

if [[ $str =~ ^[0-9]+$ ]]; then
    echo "str 是一个纯数字字符串"
fi

需要注意的是,在 [[ 和 ]] 中,变量不需要使用引号括起来,而且可以直接进行字符串比较、正则表达式匹配等操作。此外,[[ 和 ]] 也支持逻辑运算符(&&、||、!)来组合多个条件

脚本

[root@shell /server/scripts]$ cat xshell.sh
echo 当前的主机名称为: `hostname`
echo 当前的ip地址为: `hostname -I | awk ‘{print $1}’`
echo 当前的外网ip为: `curl cip.cc -s | awk ‘/IP/{print $3}’`
echo 当前的虚拟平台是: `hostnamectl | awk -F ‘:’ ‘NR==6{print $2}’`
echo 当前的系统版本是: `hostnamectl | awk -F ‘:’ ‘NR==7{print $2}’`
echo 当前的cpu的使用率: `top -n 1 -b | awk ‘/%Cpu/{print $2″%”}’`
echo 当前的内存的使用率: `free | awk ‘/Mem/{print $3/$2*100″%”}’`
echo 当前的磁盘的使用率: `df -h | awk ‘NR==6{print $5}’`
echo 当前的内核版本是: `hostnamectl | awk -F ‘:’ ‘NR==9{print $2}’`

[root@shell /server/scripts]$ sh xshell.sh
当前的主机名称为: shell
当前的ip地址为: 10.0.0.65
当前的外网ip为: 153.142.45.122
当前的虚拟平台是: vmware
当前的系统版本是: CentOS Linux 7 (Core)
当前的cpu的使用率: 0.0%
当前的内存的使用率: 8.10687%
当前的磁盘的使用率: 5%
当前的内核版本是: Linux 3.10.0-1127.el7.x86_64

作者 dmxsp

发表回复

您的电子邮箱地址不会被公开。