linux中shell脚本之变量类型、算数运算符、条件测试

一、bash中的变量类型

本地变量:仅对当前shell有效,对其子shell无效

变量赋值:name=value

name=$user

name=`Command` ,name=$(Command):这里需要注意的是“ 和 $()的意义是不同的。

从下图可以总结如下:如果将命令的执行结果赋值给一个参数时,且包含多对反引号嵌套的时候,最好外层用$()

#!/bin/bash
#
Sum=$(echo `seq $1 $2` | tr " " "+" | bc)   #################可以正确输出
echo "$1到$2的和为:$Sum"

Sum1=`echo `seq $1 $2` | tr " " "+" | bc`   #################输出报错
echo "$1到$2的和为:$Sum1"
root@cenots6.8  /testdir # ./13sum.sh 1 100
1到100的和为:5050
./13sum.sh: command substitution: line 7: syntax error near unexpected token `|'
./13sum.sh: command substitution: line 7: ` | tr " " "+" | bc'
./13sum.sh: line 7: 1: command not found
1到100的和为:
root@cenots6.8  /testdir # echo `seq 1 10`
1 2 3 4 5 6 7 8 9 10
root@cenots6.8  /testdir # echo `echo `seq 1 10``
seq 1 10
root@cenots6.8  /testdir # echo $(echo `seq 1 10`)
1 2 3 4 5 6 7 8 9 10
root@cenots6.8  /testdir # echo "echo `seq 1 10`"
echo 1
2
3
4
5
6
7
8
9
10
变量引用:$name,${name}

显示已定义的所有变量:set

删除变量:unset name

环境变量:对当前shell及其子shell有效

变量赋值:export name=value

declare -x name=value

显示所有环境变量:export、env、printenv

删除变量:unset name

bash内置的环境变量有:PATH, SHELL, USRE,UID,HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1

局部变量:对当前shell进程中某段代码片段有效(通常指函数)

位置变量:$1 $2……表示,用于让脚本在脚本代码中通过调用命令行中的传递的参数,1和2 分别代表第一个参数和第二个参数,shift可以替换参数

特殊变量:$?:判断执行结果0-255

$0:脚本名称

$*:命令行中传递的所有参数,且当做一个整体

$@:命令行传递的所有参数,每个参数当做一个整体

$#:命令行中传递的参数总数,与$@只在被双引号包起来才会看出差异,可从下段脚本中看去区别

root@Centos7.2  /testdir # cat arg1.sh arg2.sh
#!/bin/bash
#
echo 1st is $1
echo 2st is $2
echo all args are is "$*"
#!/bin/bash
#
./arg1.sh "$*"

echo ============i

./arg1.sh "$@"

echo ==============

echo $*
echo $@
root@Centos7.2  /testdir # ./arg2.sh 1 2 3
1st is 1 2 3
2st is
all args are is 1 2 3
============i
1st is 1
2st is 2
all args are is 1 2 3
==============
1 2 3
1 2 3
只读变量:只读变量不能修改删除

变量赋值:readonly name=value 、declare -r  name=value

PATH变量定义位置:.bash_profile  –>  $PATH:$HOME/bin

PATH=$PATH:$HOME/.local/bin:$HOME/bin     –.local/bin  centos7普通用户有的隐藏的目录,可以放写隐藏的脚本

写脚本的时候可以先mkdir /home/bin 在bin目录下写脚本,可省去相对路径。

source bash.sh 也可以执行脚本:其执行过程相当于直接在当前shell进程中进行,而不是开一个子进程进行,所有脚本执行完,echo 变量,还可以查看到变量的值。(正常父进程是不能查看子进程的变量的)

shadow 默认权限000  但是root用户属于超级用户 可读可写,但是如果文件没有x权限,root也不能执行

二、算数运算符

bash中的算数运算符:+、-、*、/、%、**(平方) 注意:在使用expr的时候“*” 要转义“\*”

实现算数运算:

let var=算数表达式

var=$[算数表达式]

var=$((算数表达式))

var=$(expr arg1 arg2 arg3)   注意:每个参数之间要用空格隔开

            root@cenots6.8 # echo $(expr 5 \* 2 - 1)
            9
declare -i var=数字

echo ‘算数表达式’| bc

随机数生成器:echo $[RANDOM%50]:0-49之间的随机数

echo $[RANDOM%50+1]:1-50之间的随机数

$RANDOM :1-32767

三、聚合命令

#!/bin/bash

echo xxx;(echo zzz;exit)     ############():代表开个子shell,exit退出子shell非当前shell

echo yyy

四、退出状态码

0 代表成功, 1-255代表失败

$? 变量保存最近的命令退出状态

我们也可以指定程序退出的状态码,根据状态码的数值,来判断工作状态,脚本中一旦遇到exit命令,脚本会立即终止,终止,终止退出状态取决于exit命令后面的数字,如果没有执行exit,则取脚本最后一条命令的执行状态结果。

五、条件测试

测试命令:test [expression]

[ $a = $b ]           判断 一对[]或两对[[]] 都可以

[[ $a == $b ]]      两个等号也可以 

[ -f /bin/cat -a -x /bin/cat ]    此时必须使用 一对[]  否则会报错

数值测试:

-gt:大于

-ge:大于等于

-lt:小于

-le:小于等于

-eq:等于

-ne:不等于

字符串测试:

==:是否相等

>:大于(比较ascll码)

<:小于

!=:是否不等于

=~:左侧字符串是否能够被右侧的PATTERN所匹配,注意: 此表达式一般用于[[ ]]中;

-z “string”:判断字符串是否为空,如果为空则为真

-n “string”:判断字符串是否为空,如果不为空则为真

注意:用于字符串比较的时候,操作数应该使用引号

存在性测试:

-a file:文件存在为真,否则为假

-e file:同-a

存在性及类别测试:

-b FILE:是否存在且为块设备文件            block

-c FILE:是否存在且为字符设备文件         char

-d FILE:是否存在且为目录文件                dir

-f FILE:是否存在且为普通文件               

-h FILE 或 -L FILE:存在且为符号链接文件

-p FILE:是否存在且为命名管道文件

-S FILE:是否存在且为套接字文件

文件权限测试:

-r FILE:是否存在且可读

-w FILE: 是否存在且可写

-x FILE: 是否存在且可执行                    

文件特殊权限测试:

-g FILE:是否存在且拥有sgid权限

-u FILE:是否存在且拥有suid权限

-k FILE:是否存在且拥有sticky权限

文件大小测试:

-s FILE: 是否存在,非空为真,否则为假

文件是否打开:

-t fd: fd表示文件描述符是否已经打开且与某终端相关

-N FILE:文件自动上一次被读取之后是否被修改过

-O FILE:当前有效用户是否为文件属主

-G FILE:当前有效用户是否为文件属组

双目测试:

FILE1 -ef FILE2: FILE1与FILE2是否指向同一个设备上的相同inode

FILE1 -nt FILE2: FILE1是否新于FILE2;

FILE1 -ot FILE2: FILE1是否旧于FILE2;

组合测试条件:

第一种方式:

COMMAND1 && COMMAND2 并且

COMMAND1 || COMMAND2 或者

! COMMAND 非

如: [ -e FILE ] && [ -r FILE ]

第二种方式:

EXPRESSION1 -a EXPRESSION2 并且

EXPRESSION1 -o EXPRESSION2 或者

! EXPRESSION

一、作业:

1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。

#!/bin/bash
#编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。
IPaddr=`ifconfig | sed -n '2p'| sed 's@.*inet addr:@@g' | sed 's@Bc.*@@'`
SysVersion=`cat /etc/redhat-release`
CPU=`sed -n "5p" /proc/cpuinfo |cut -d: -f2|tr -d " "`
MemInfo=`sed -n '1p' /proc/meminfo |cut -d: -f2|tr -d " "`
FdiskInfo=`fdisk -l |sed -n '2p' | grep -o ".*GB"| sed -r "s@Dis.*: @@"`
echo "HostName: `hostname`"
echo "Ipaddress: $IPaddr"
echo "SysVersion: $SysVersion"
echo "KernelVersion: `uname -r`"
echo "CPU: $CPU"
echo "MemInfo: $MemInfo"
echo "FdiskInfo: $FdiskInfo"

unset IPaddr
unset SysVersion
unset CPU
unset MemInfo
unset FdiskInfo
root@cenots6.8  /testdir # ./systeminfo.sh
HostName: cenots6.8
Ipaddress: 10.1.249.49 
SysVersion: CentOS release 6.8 (Final)
KernelVersion: 2.6.32-642.el6.x86_64
CPU: Intel(R)Core(TM)i5-5200UCPU@2.20GHz
MemInfo: 1004136kB
FdiskInfo: 128.8 GB
2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中

#!/bin/bash
#编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中
dirName="/root/etc`date +%F`"
cp -a /etc $dirName && echo " 备份成功"
root@cenots6.8  /testdir # ls -d ~/etc* ; du -sh ~/etc*
/root/etc2016-08-12
41M    /root/etc2016-08-12
3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值

#!/bin/bash
#编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
Use=`df | tr -s " "|cut -d" " -f5|sed -n '1!p'|sort -n|tr -d % |tail -1`
[ $Use -gt 10 ] && wall disk will be full!
unset Use
root@cenots6.8  /testdir # ./checkdisk.sh

Broadcast message from root@cenots6.8 (pts/1) (Fri Aug 12 10:38:52 2016):

disk will be full
4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序

#!/bin/bash
#编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序
linCount=`netstat -t | grep "tcp" | tr -s " " | cut -d" " -f5 | sed "s@:.*@@" | sort -n | uniq -c`
echo -e “链接数    IP地址”
echo -e "$linCount"
root@cenots6.8  /testdir # ./links.sh
“链接数 IP地址”
      2 10.1.250.130
5、写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和

#!/bin/bash
#写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和
UserId10="`sed -n '10p' /etc/passwd | cut -d: -f3`"
UserId20="`sed -n '20p' /etc/passwd | cut -d: -f3`"
SumId=$[UserId10+UserId20]
echo "第10个用户和第20用户的ID之和为:$SumId"

unset UserId10
unset UserId20
unset SumId
root@cenots6.8  /testdir # ./sumid.sh
第10个用户和第20用户的ID之和为:180
6、写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和

#!/bin/bash
#写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
File1="`grep "^$" $1 | wc -l`"
File2="`grep "^$" $2 | wc -l`"
SpaceSum=$[File1+File2]
echo "两个文件中所有空白行之和: $SpaceSum "

unset File1
unset File2
unset SpaceSum
root@cenots6.8  /testdir # ./sumspace.sh /etc/profile /etc/fstab
两个文件中所有空白行之和: 12
7、写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件

#!/bin/bash
#写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件#
EtcNum="`ls /etc/ | wc -l`"
VarNum="`ls /var/ | wc -l`"
UsrNum="`ls /usr/ | wc -l`"
SumFile=$[$EtcNum+$VarNum+$UsrNum]
echo "The Sumfile: $SumFile"

unset EtcNum
unset VarNum
unset UsrNum
unset SumFile
root@cenots6.8  /testdir # ./sumfile.sh
The Sumfile: 287
8、写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数

#!/bin/bash
#写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参
数所指向的文件中的空白行数
[[ $# -lt 1 ]] && echo "至少应该给一个参数" ||  echo "SpaceNum: `grep "^$" $1 | wc -l`"
root@cenots6.8  /testdir # ./argsnum.sh
至少应该给一个参数
root@cenots6.8  /testdir # ./argsnum.sh /etc/profile
SpaceNum: 11
9、写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”

#!/bin/bash
#
ping -c1 -W2 $1 &> /dev/null && echo "该IP地址可访问" || echo "该IP地址不可访问"
root@cenots6.8  /testdir # ./hostping.sh 10.1.249.48
该IP地址可访问
root@cenots6.8  /testdir # ./hostping.sh 10.1.249.4
该IP地址不可访问
10、chmod -rw /tmp/file1,编写脚本/root/bin/per.sh,判断当前用户对/tmp/fiile1文件是否不可读且不可写

#!/bin/bash
#
[ -r /testdir/file1 -a -w /testdir/file1 ] && echo "`whoami` 可读可写" || echo "`whoami`非可读可写"
root@cenots6.8  /testdir # ./per.sh
root 可读可写
tom@cenots6.8  /testdir # ./per.sh
tom非可读可写
11、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统。

#!/bin/bash
#编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统。
[ ! -f /etc/nologin ] && echo "普通用户已不可以登陆系统" && touch /etc/nologin

[ -f /etc/nologin ] && echo "普通用户已可以登陆系统" && rm -rf  /etc/nologin
root@cenots6.8  /testdir # ./login.sh  #########################禁止普通用户登陆
普通用户已不可以登陆系统
[c:\~]$ ssh tom@10.1.249.49

Connecting to 10.1.249.49:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

Connection closed by foreign host.

Disconnected from remote host(10.1.249.49:22) at 12:09:27.

Type `help' to learn how to use Xshell prompt.
root@cenots6.8  /testdir # ./login.sh ##########################允许普通用户登陆
普通用户已可以登陆系统
[c:\~]$ ssh tom@10.1.249.49

Connecting to 10.1.249.49:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

tom@cenots6.8  ~ #
12、写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,先判断是否合格IP,否,提示IP格式不合法并退出,是,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”

#!/bin/bash
#
echo "$1" | grep -E -qo  '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])' && ( ping -c1 -W2 $1 &> /dev/null && echo "该IP地址可以访问" || echo "该IP地址不可以访问") || echo "该IP地址不合法";exit 1
root@cenots6.8  /testdir # ./hostping.sh
该IP地址不合法
root@cenots6.8  /testdir # ./hostping.sh 10.1.249.49
该IP地址可以访问
root@cenots6.8  /testdir # ./hostping.sh 192.192.192.192
该IP地址不可以访问
13、计算1+2+3+…+100的值

#!/bin/bash
#
Num=`echo {1..100} | tr " " "+" | bc`
echo "$1到$2的和为:$Num"
root@cenots6.8  /testdir # ./13sum.sh
到的和为:5050
#!/bin/bash
#
Sum=$(echo `seq $1 $2` | tr " " "+" | bc)
echo "$1到$2的和为:$Sum"
root@cenots6.8  /testdir # ./13sum.sh 1 100
1到100的和为:5050
14、计算从脚本第一参数A开始,到第二个参数B的所有数字的总和,判断B是否大于A,否提示错误并退出,是则计算之

#!/bin/bash
#计算从脚本第一参数A开始,到第二个参数B的所有数字的总和,判断B是否大于A,否提示错误并退出,是则计算之
Sum=$(echo `seq $1 $100` | tr " " "+" | bc)
[ $1 -lt $2 ] && echo $1到$2的和为:$Sum || echo "$1 不能大于 $2" ;exit 1
root@cenots6.8  /testdir # ./14sum.sh 1 100
1到100的和为:5050
root@cenots6.8  /testdir # ./14sum.sh 100 1
100 不能大于 1

时间: 2024-09-12 14:13:42

linux中shell脚本之变量类型、算数运算符、条件测试的相关文章

应用-Linux中shell脚本问题

问题描述 Linux中shell脚本问题 ]我有shell脚本,放在/bin/目录下,内容如下: #!/bin/sh cd /usr /sbin/insmod s3c_ts.ko ./digitpic ./MSYH.TTF & 当我开发板上电以后我手动执行手动执行test.sh 我的digitpic应用程序能够正常启动 当我在/etc/init.d/rcS 文本里面最后添加exec test.sh 提示说这个触摸屏读取错误,也就是/sbin/insmod s3c_ts.ko这部分错误了,就只有触

linux中shell脚本进行MySQL数据库定时备份

具体方法  代码如下 复制代码 #!/bin/bash #Shell Command For Backup MySQL Database Everyday Automatically By Crontab #Author : Carlos Wong #Date : 2010-08-24 #配置参数  代码如下 复制代码 USER=root #数据库用户名" >用户名 PASSWORD=××××× #数据库用户密码 DATABASE=TIENIUZAI    #数据库名称 WEBMASTER

linux中shell脚本实现下载完关机_linux shell

用mint 有一段时间了,下载基本用firefox,有时下载几个G的游戏.可是firefox没有找到下载完关机的选择.处于这个原因,写了这个. download_shutdown.sh #!/bin/bash # Created By: Demo <demo@demo.com> # Created Time: 2015-01-30 12:36:44 # Modified Time: 2015-01-30 12:54:21 dir=$1 while [ "1" ] do if

linux中SHELL脚本中的数组用法

在Shell中(我这里是Bash),其实没有传统意义上的"数据类型",把任何变量中存的值都是作为字符组成的"字符串".当然,通过declare可以声明某个变量是整型.数组等类型.其中,数组就是本文要专门讲的了.在Bash中,仅支持一维数组,当然通过关联数组(associative array)的形式可以模拟多维数组. 1. 数组的声明 用 declare -a array 声明array是一个数组,用declare -A a_array 声明a_array是一个关联

linux中shell脚本监控网站80端口与网站是否正常

监控网站80端口 很多时候我们不知道网站80端口是否正常,当然我以前的shell监控网站状态(续)这篇文章也可以监控网站,这里只是给大家提供另外一个思路去监控网站. 脚本内容:  代码如下 复制代码 vi check-80.sh #!/bin/bash nmap -P0 -p80 -sS -vv blog.slogra.com|grep 80 |tail -n1>/tmp/nmap.txt check_80=`cat /tmp/nmap.txt|awk '{print $2}'` if [ &quo

linux中shell脚本数组的操作教程

数组赋值:a=(1 2 3 4 5) a[1]=1 数组长度:echo ${#a[@]} 或者 echo ${#a[*]} 读取数组:echo ${a[@]} 或者 echo ${a[*]} echo ${a[0]}                             PS: 数组下标从0开始 删除数组:unset a unset a[1] 数组分片:echo ${a[@]:0:3}                  显示为1,2,3                ps:截取前3个数组值显示

linux中shell脚本导出备份mysql数据库

最近公司有个需求需要从mysql数据库中查询状态为60的数据并导出. 实例代码如下: #!/bin/bash   dir="/cache1" ##要存到导出数据的目录名 open="open" ##导出数据的文件名称 open_dir="${open}.$(date +%Y%m%d)" ##导出数据的文件名称,按日期区分 db="/opt/trustedm/mysql/current/bin/mysql -uroot -pmv_XQ_m

linux中Shell脚本所在目录的绝对路径

 代码如下 复制代码 baseDirForScriptSelf=$(cd "$(dirname "$0")"; pwd) echo "full path to currently executed script is : ${baseDirForScriptSelf}" 或者 FULLPATH=$(cd "$(dirname "$0")"; pwd) echo "full path to curr

linux中Shell脚本分割Nginx日志,并定期清理例子

一:新建脚本文件 vim cut_nginx_log.sh #!/bin/bash #nginx access log segmentation shell script #www.webyang.net #日志目录 log_dir="/usr/local/nginx/logs/" cd $log_dir time=`date +%Y%m%d --date="-1 day"` #nginx启动目录 nginx_dir="/etc/init.d/nginx&