Shell编程及Bash

为什么学习shell编程?

对于一个合格的系统管理员来说,学习和掌握Shell编程是非常重要的。通过编程,可以在很大程度上简化日常的维护工作,使得管理员从简单的重复劳动中解脱出来。
Shell程序的特点:
1、简单易学。
2、解释性语言,不需要编译即可执行。


shell 特性

什么是shell???

Shell又称命令解释器,它能识别用户输入的各种命令,并传递给操作系统。它的作用类似于Windows操作系统中的命令行,但是,Shell的功能远比命令行强大的多。在UNIX或者localhost中,Shell既是用户交互的界面,也是控制系统的脚本语言。
在这里插入图片描述

shell种类

Bourne Shell:标识为sh,该Shell由Steve Bourne在贝尔实验室时编写。在许多Unix系统中,该Shell是root用户的默认的Shell。
Bourne-Again Shell:标识为bash,该Shell由Brian Fox在1987年编写,是绝大多数linux发行版的默认的Shell。
Korn Shell:标识为ksh,该Shell由贝尔实验室的David Korn在二十世纪八十年代早期编写。它完全向上兼容 Bourne Shell 并包含了C Shell 的很多特性。
C Shell:标识为csh,该Shell由Bill Joy在BSD系统上开发。由 于其语法类似于C语言,因此称为C Shell。

什么是shell脚本?

当命令或程序语句不在命令行下执行,而是通过一个程序文件来执行,该程序文件即脚本。

Shell脚本运行

方法一:切换到shell脚本所在的目录(此时,称为工作目录)执行shell脚本
方法二:以绝对路径的方式去执行bash shell脚本:
方法三:直接使用bash 或sh 来执行bash shell脚本:
方法四:在当前的shell环境中执行bash shell脚本:source或.
区别: 1、方法三:可以在脚本中不指定解释器,脚本可以没有执行权限
2、方法一和方法二脚本需要有执行权限,./script_name.sh 或 /path/script_name.sh
3、方法四:当前shell执行,方法1-3开启子shell

shell脚本注释

通过在代码中增加注释可以提高程序的可读性。传统的Shell只支 持单行注释,其表示方法是一个井号“#”,从该符号开始一直到行尾都属于注释的内容。
多行如何注释?
用户还可以通过其他的一些变通的方法来实现多行注释,其中,最简单的方法就是使用冒号“:”配合here document,语法如下:
:<<BLOCK
注释内容
BLOCK

shell脚本规范

开头指定脚本解释器
#!/bin/sh或#!/bin/bash
其他行#表示注释
名称见名知义 backup_mysql.sh,以sh结尾
#Date: 创建日期
#Author: 作者
#Mail: 联系方式
#Function: 功能
#Version: 版本

Shell中会使用的一些查询命令

Vi及Vim解析

Vi及Vim用法及命令

Grep及基本正则表达式

正则表达式就是为了处理大量的文本|字符串而定义的一套规则和方法
对于系统管理员来讲,正则表达式贯穿在我们的日常运维工作中,无论是查找某个文档,抑或查询某个日志文件分析其内容,都会用到正则表达式

Linux中的正则表达式,常应用正则表达式的命令是grep(egrep),sed,awk。Linux下三剑客!
正则表达式分为两种:

  • 基本正则表达式(BRE,basic regular expression)
  • 扩展正则表达式(ERE,extended regular expression)
参数 作用
–color 匹配到的字符串显示颜色
-i 忽略字符大小写
-o 仅显示匹配的字串
-v 反向选取, 即显示不匹配的行
-E 使用扩展正则表达式
-n 显示行号
-w 匹配指定的字符串
元数据 意义和范例
^word 搜寻word开头的行
搜寻以#开头的行,grep -n ‘^#’ file
word$ 搜寻word结尾的行
搜寻以.结尾的行,grep -n ‘.$’ file
. 匹配任意一个字符
匹配e和e之间有任意一个字符,grep -n ‘e.e’ file
\ 转义字符
* 前面的一个字符重复0到多次
匹配gle,gogle,google,gooogle等,grep -n ‘go*gle’ file
[list] 匹配一系列字符中的一个
[n1-n2] 匹配一个字符范围中的一个字符
匹配数字字符,grep -n ‘[0-9]’ file
[^list] 匹配字符集以外的字符
匹配非o字符,grep -n ‘[^o]’ file
{n1,n2} 前面的单个字符重复n1,n2次
匹配google,gooogle,grep -n ’ go{2,3}gle ’ file
<word 单词的开头
匹配以g开头的单词,grep -n <g file
word> 单词的结尾
匹配以tion结尾的单词,grep -n tion> file
‘ ‘ 强引用,引号内的内容不变
“ ” 弱引用,变量会替换
[[:alnum:]] 代表英文大小写字符及数字,即 0-9, A-Z, a-z
[[:alpha:]] 代表任何英文大小写字符,即 A-Z, a-z
[[:space:]] 任何会产生空白的字符,包括空白键, [Tab] 等等
[[:digit:]] 代表数字,即 0-9
[[:lower:]] 代表小写字符,即 a-z
[[:upper:]] 代表大写字符,即 A-Z

egrep及扩展正则表达式

grep一般情况下支持基本正则表达式,可以通过参数-E支持扩展正则表达式,另外grep单独提供了一个扩展命令叫做egrep用来支持扩展正则表达式,这条命令和grep -E等价(grep -E == egrep)
一般情况下,基本正则表达式就够用了
特殊情况下,复杂的扩展表达式,可以简化字符串的匹配
扩展正则表达式就是在基本正则表达式的基础上,增加了一些元数据

元数据 意义和范例
+ 重复前面字符1到多次
匹配god,good,goood等字符串,grep -nE go+d’ file
? 匹配0或1次前面的字符
匹配gd,god,grep -nE ‘go?d’ file
| 或or的方式匹配多个字符串
匹配god或者good,grep -nE’god
() 匹配整个括号内的字符串,原来都是匹配单个字符
搜索good或者glad,grep -nE 'g(oo
* 前面的字符重复0到多次

例题:

#1、显示/proc/meminfo文件中以大小s开头的行(要求:使用两种方法) 
cat /proc/meminfo |grep -i "^s" cat /proc/meminfo |grep  "^\(s\|S\)"
 
#2、显示/etc/passwd文件中不以/bin/bash结尾的行 
cat /etc/passwd |grep -v ":/bin/bash$"
 
#3、显示用户rpc默认的shell程序 
cat /etc/passwd |grep -w "^rpc" |cut -d: -f 7
 
#4、找出/etc/passwd中的两位或三位数 
cat /etc/passwd |grep -wo "[[:digit:]]\{2,3\}"
 
#5、显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面有非空白字符的行 
cat /etc/grub2.cfg | grep "^[[:space:]]\+[^' '].*" cat /etc/grub2.cfg | grep "^[[:space:]]\+[^[:space:]].*"
 
#6、找出“netstat -tan”命令结果中以LISTEN后跟任意多个空白字符结尾的行 
netstat -tan | grep ".*LISTEN[[:space:]]*$"
 
#7、显示CentOS7上所有系统用户的用户名和UID 
cat /etc/passwd |cut -d: -f1,3 |grep -w "[1-9][0-9]\{,2\}$"
 
#8、添加用户bash、testbash、basher、sh、nologin(其shell为/sbin/nologin),找出/etc/passwd用户名和shell同名的行 
cat /etc/passwd |grep -w "^\([^:]*\):.*/\1$"
 
#9、利用df和grep,取出磁盘各分区利用率,并从大到小排序 
df |grep "^/dev/sd"|grep -wo "[0-9]\+%"|sort -nr
 
#10、显示三个用户root、mage、wang的UID和默认shell 
cat /etc/passwd |grep -w "^\(root\|mage\|wang\)" |cut -d: -f 3,7
 
#11、找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行 
cat /etc/rc.d/init.d/functions |grep -i "^\([_[:alnum:]]\+(\)"
 
#12、使用egrep取出/etc/rc.d/init.d/functions中其基名 
echo "/etc/rc.d/init.d/functions" | grep -Eo "[^/]*[/]?$"|tr -d "/"
 
#13、使用egrep取出上面路径的目录名 
echo "/etc/rc.d/init.d/" | grep -Eo ".*[/]\<"
 
#14、统计last命令中以root登录的每个主机IP地址登录次数 
last |grep -w "^root.*\<pts" |  grep -wE "((([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])){1}[[:space:]]" |tr -s " "|cut -d " " -f3|sort|uniq -c  
 
#15、利用扩展正则表达式分别表示0-9、10-99、100-199、200-249、250-255 
[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]
 
#16、显示ifconfig命令结果中所有IPv4地址 
ifconfig |grep -owE "((([0-9]{1,2})|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))[.]){3}(([0-9] {1,2})|(1[0-9]{,2})|(2[0-4][0-9])|(25[0-5])){1}[[:space:]]"
 
#17、将此字符串:welcome to  magedu linux 中的每个字符去重并排序,重复次数多的排到前面 
cat test | grep -o "[[:lower:]]"|sort |uniq -c|sort -nr |tr -s ' ' | cut -d " " -f 3 |tr -d '\n'
 
#18.找出ifconfig命令结果中的1-255之间的数字 
ifconfig | grep -E "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>" 
#步骤拆解 #2 
#25 
#255    
要注意规律 
#ifconfig | grep -E "\<([1-9]|[1-9][0-9])\>"    #| 为或 
#ifconfig | grep -E '\<(1[0-9][0-9])\>'     
#ifconfig | grep -E '\<(2[0-4][0-9]|25[0-5])\>' 

截取文件test内的内容:
"Open Source" is a good mechanism to develop programs.
apple is my favorite food.
Football game is not use feet only.
this dress doesn’t fit me.
However, this dress is about $ 3183 dollars.^M
GNU is free air not free beer.^M
Her hair is very beauty.^M
I can’t finish the test.^M
Oh! The soup taste good.^M
motorcycle is cheap than car.
This window is clear.
the symbol ‘*’ is represented as start.
Oh! My god!
The gd software is a library for drafting programs.^M
You are the best is mean you are the no. 1.
The world is the same with “glad”.
I like dog.
google is the best tools for search keyword.
goooooogle yes!
go! go! Let’s go.
# I am ghost

#19. 取得 test 或 taste 这两个单字相关信息及行号 
grep -n 't[ae]st' test

#20.不想取 oo 前面有 g 的字符相关信息及行号
grep -n 'oo' test | grep -v 'goo' 

#21.oo 前面不想要有小写的字符相关信息及行号 
grep -n 'oo' test | grep -v '[[:lower:]]oo'

#22.取得行尾结束为小数点相关信息及行号
grep -n '\.$' test 

#23.取得空白行相关信息及行号
grep -n '^$' test

#24.取得g??d 的字符相关信息及行号
grep -n 'g..d' test

#25.取得至少两个 o 以上的字符相关信息及行号
grep -n 'o\{2\}' test

#26.取得开头与结尾都是 g ,两个g 之间仅能存在至少一个 o 相关信息及行号
grep -n 'go*g' test

#27.取得g 开头与 g 结尾的字符,当中的字符可有可无 相关信息及行号
grep -n 'g.*g' test

#28.取得g 后面连接2到5个 o,然后再接一个 g 的字符相关信息及行号
grep -n 'go\{2,5\}g' test

sort 排序

sort 就是将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
sort 参数 文件(-o 输出文件)

参数 作用
-b 忽略每行开头空格字符
-c 检查文件是否已按顺序排序
-f 忽略大小写
-M 将前三个字母按月份进行排序
-n 依照数值大小进行排序
-o 输出文件
-r 以从大到小排序
-t <分隔符> 指定排序区间分隔符
-k 选择排序区间
-u 去除重复项

sort

[root@linux project]# cat test1
apple
xiaomi
google
apple
baidu
sohu
android
xunlei
[root@linux project]# sort test1
android
apple
baidu
google
sohu
xiaomi
xunlei

sort -u 去除重复行

[root@linux project]# cat test1
apple
xiaomi
google
apple
baidu
sohu
android
xunlei
[root@linux project]# sort -u test1
android
apple
baidu
google
sohu
xiaomi
xunlei

当-u和-k一起使用时,sort只会对-k参数指定的部分进行比较,若-k指定部分相同则一样会过滤掉不输出。

sort -r 将文件降序排列

[root@linux project]# cat test1
apple
xiaomi
google
apple
baidu
sohu
android
xunlei
[root@linux project]# sort -r test1
xunlei
xiaomi
sohu
google
baidu
apple
android

sort -o 将文件内容排序并输出到另一个文件

由于sort默认是把结果输出到标准输出,所以需要用重定向才能将结果写入文件,形如sort filename > newfile。
但如果想把排序结果输出到原文件中,用重定向可就不行了。
[rocrocket@rocrocket programming]$ sort -r number > number
[rocrocket@rocrocket programming]$ cat number
[rocrocket@rocrocket programming]$
number清空了!!!
所以在这里我们就需要用-o参数

[root@linux project]# cat number
1
3
5
2
4
[root@linux project]# sort -r number -o number
[root@linux project]# cat number
5
4
3
2
1

sort -n 以数值number大小排序

[root@linux project]# cat number 
3
25
1
564
43
47
234
4
56725
1
324
4
32
[root@linux project]# sort number 
1
1
234
25
3
32
324
4
4
43
47
564
56725
[root@linux project]# sort -n number 
1
1
3
4
4
25
32
43
47
234
324
564
56725

sort -t 以指定的分隔符排序 -k 以指定的列进行排序

在sort排序中,-t如果不指定分隔符时,一般默认以空格作为分隔符
sort中-t和-k一般结合使用,例如:

[root@linux project]# cat test3
apple:50:5000
android:60:6000
google:100:5500
baidu:110:5500
sohu:55:7000
xiaomi:65:4000
xunlei:50:6000
[root@linux project]# sort -n -t: -k2 test3
apple:50:5000
xunlei:50:6000
sohu:55:7000
android:60:6000
xiaomi:65:4000
google:100:5500
baidu:110:5500

例题:

[root@linux project]# cat test2
apple 50 5000
android 60 6000
google 100 5500
baidu 110 5500
sohu 55 7000
xiaomi 65 4000
xunlei 50 6000

以空格作为分隔符,以第二列数据作为排序标准,若第二列中有重复数据则比较第三列:

[root@linux project]# sort -n -t' ' -k 2,3 test2
apple 50 5000
xunlei 50 6000
sohu 55 7000
android 60 6000
xiaomi 65 4000
google 100 5500
baidu 110 5500

以空格作为分隔符,只以第一列的第二位作为排序标准,若有重复数据则只比较第三列:

[root@linux project]# sort -n -t' ' -k 1.2,1.2 -k 3,3 test2
xiaomi 65 4000
apple 50 5000
baidu 110 5500
google 100 5500
android 60 6000
xunlei 50 6000
sohu 55 7000
注意这个例子
[root@linux project]# sort -n -k 2.2,3.1 test2
apple 50 5000
android 100 6000
google 100 5500
baidu 110 5500

以第二个域的第二个字符开始到第三个域的第一个字符结束的部分进行排序。
第一行,会提取0 5,第二行提取00 6,第三行提取00 5,第四行提取10 5。
又因为sort认为0小于00小于000小于0000….

原因:sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分,而不会把第三个域的开头字符纳入比较范围。当发现00和00相同时,sort就会自动比较第一个域去了。当然baidu在sohu前面了。
用一个范例即可证实:

[root@linux project]# sort -n -k 2.2,3.1 -k3.1 test2
apple 50 5000
google 100 5500
android 100 6000
baidu 110 5500

diff 命令

diff 命令用于比较多个文本文件的差异,格式为“diff [选项] 文件”。

使用 cat 命令分别查看 diff_A.txt 和 diff_B.txt 文件的内容,然后进行比较:

[root@linux ~]# cat diff_A.txt Welcome to linux.com
Red Hat certified Free Linux Lessons
[root@linux ~]# cat diff_B.txt


Welcome to linux.com #Red Hat certified
Free Linux Lessons

使用 diff --brief 命令显示比较后的结果,判断文件是否相同:

[root@linux ~]# diff --brief diff_A.txt diff_B.txt 
Files diff_A.txt and diff_B.txt differ

使用带有-c 参数的 diff 命令来描述文件内容具体的不同:

[root@linux ~]# diff -c diff_A.txt diff_B.txt
*** diff_A.txt  2018-08-16 05:54:38.440500149 -0400
--- diff_B.txt   2018-08-16 05:55:09.921497634 -0400
***************
*** 1,3 ****
Welcome to linux.com
! Red Hat certified Free Linux Lessons
--- 1,3 ----
Welcome to linux.com
! #Red Hat certified

Free Linux Lessons

使用 diff 命令结合后面要讲的重定向,生成一个补丁文件,其中,字母"a"、“d”、"c"分别表示添加、删除及修改操作。

[root@linux mnt]# diff diff_A.txt diff_B.txt 1,3c1,3
< Welcome to linux.com
< #Red Hat certified
< Free Linux Lessons
---
> Welcome tooo linux.com
> Red Hat certified
> Free Linux LeSSonS
[root@linux mnt]# diff diff_A.txt diff_B.txt > path.file [root@linux mnt]# cat path.file
2c2
< Red Hat certified
---
> #Red Hat certified
参数 作用
-u 显示有差异行的前后几行(上下文), 默认是前后各 3 行, 这样,
patch 中带有更多的信息.,
-p 显示代码所在的 c 函数的信息。
-r 递归地对比一个目录和它的所有子目录(即整个目录树)。
-N 如果某个文件缺少了, 就当作是空文件来对比. 如果不使用本选项, 当 diff 发现旧代码或者新代码缺少文件时, 只简单的提示缺少文件. 如果使用本选项, 会将新添加的文件全新打印出来作为新增的部分.

patch 命令

patch 被用于为开放源代码软件安装补丁程序。让用户利用设置修补文件的方式,修改,更新原始文件。

使用 diff 命令生成的 patch.file 为 diff_A.txt 升级或者还原

[root@linux mnt]# patch diff_A.txt < path.file patching file diff_A.txt
[root@linux mnt]# patch -R diff_A.txt < path.file patching file diff_A.txt

tr 命令

tr 命令用于替换文本文件中的字符,格式为“tr [原始字符] [目标字符]”。

把某个文本内容中的英文全部替换为大写

[root@linux ~]# cat anaconda-ks.cfg | tr [a-z] [A-Z] #VERSION=DEVEL
# SYSTEM AUTHORIZATION INFORMATION AUTH --ENABLESHADOW --PASSALGO=SHA512


# USE CDROM INSTALLATION MEDIA CDROM
# USE GRAPHICAL INSTALL GRAPHICAL
# RUN THE SETUP AGENT ON FIRST BOOT FIRSTBOOT --ENABLE
IGNOREDISK --ONLY-USE=SDA # KEYBOARD LAYOUTS
KEYBOARD --VCKEYMAP=US --XLAYOUTS='US' # SYSTEM LANGUAGE
LANG EN_US.UTF-8

# NETWORK INFORMATION
NETWORK --BOOTPROTO=DHCP --DEVICE=ENO16777728 --ONBOOT=OFF -- IPV6=AUTO
NETWORK --HOSTNAME=linux.COM

# ROOT PASSWORD ROOTPW --ISCRYPTED
$6$HFRQIKOPAK5JQAWM$AVUYZ3JQZ4WAWCPLRHBPM08GNDZRBIVU2BG.RTM IXVZODSZK/PFUZJ8OKEWE0MDCX66OK3/BNYWKYGAIPGUFP.
# SYSTEM TIMEZONE


TIMEZONE AMERICA/NEW_YORK  --ISUTC # SYSTEM BOOTLOADER CONFIGURATION
BOOTLOADER --APPEND=" CRASHKERNEL=AUTO" --LOCATION=MBR --BOOT- DRIVE=SDA
AUTOPART --TYPE=LVM
# PARTITION CLEARING INFORMATION CLEARPART --ALL --INITLABEL --DRIVES=SDA

%PACKAGES @^MINIMAL @CORE KEXEC-TOOLS

%END

%ADDON COM_REDHAT_KDUMP --ENABLE --RESERVE-MB='AUTO'

%END

Bash脚本

显示消息echo

[root@linux ~]# cat s2.sh
#!/bin/bash 
#The examples of echo command 
# 
echo "The time is:"     #字符串需要用''或""引起来 
date echo "The who's logged on:" 
who

[root@linux ~]# sh s2.sh 
The time is:
Wed Oct 31 16:51:14 CST 2018
The who's logged on:
root     tty1         2018-10-31 16:03
root     pts/0        2018-10-31 16:02 (192.168.130.1)

使用变量

[root@linux ~]# cat s3.sh
#!/bin/bash 
#The examples of '$' 
# 
echo "The user is: $USER"   #echo中可以使用$变量 
echo "The user id is: $UID" 
echo "The user directory is: $HOME"

[root@linux ~]# sh s3.sh 
The user is:root
The user id is:0
The user directory is:/root

用户变量

[root@linux ~]# cat s4.sh
#!/bin/bash
days=10
guest='alice'
echo "The user $guest logged system before $days days ago"
days=5
guest="tom"
echo "The user $guest logged system before $days days ago"

[root@linux ~]# sh s4.sh 
The user alice logged system before 10 days ago
The user tom logged system before 5 days ago

命令替换

[root@linux ~]# cat s5.sh
#!/bin/bash
time=$(date +%F-%T)
cp -a /var/log/messages /tmp/messages_bak.$time

[root@linux ~]# sh s5.sh 
[root@linux ~]# cd /tmp/
[root@linux tmp]# ls
messages_bak.2018-10-24-16:52:23

数学运算

[root@linux ~]# cat s6.sh
#!/bin/bash
var1=10
var2=20.23
result=$(echo "scale=2; $var1 + $var2" | bc)

echo The result is $result

[root@linux ~]# sh s6.sh 
The result is 30.23

[root@linux ~]# cat s7.sh
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
result=$(bc << EOF
scale = 4
a1 = ($var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
)
echo $result
[root@linux ~]# sh s7.sh 
2813.9882

Bash条件测试

[root@linux ~]# cat s8.sh 
#!/bin/bash
t_user=alice
if grep $t_user /etc/passwd
then
        echo "The user name is:$USER"
        echo "The user uid is:$UID:"
        echo "Other dir info are:"
        ls -a /home/$t_user/.b*
fi

[root@linux ~]# sh s8.sh 
alice:x:10005:10008::/home/alice:/bin/bash
The user name is:root
The user uid is:0:
Other dir info are:
/home/alice/.bash_history  /home/alice/.bash_profile
/home/alice/.bash_logout   /home/alice/.bashrc



[root@linux ~]# cat s9.sh 
#!/bin/bash
t_user=aaa
if grep $t_user /etc/passwd
then
        echo "The user $t_user exists on system"
else
        echo "The user $t_user does not exist on system."
fi

[root@linux ~]# sh s9.sh 
The user aaa does not exist on system.



[root@linux ~]# cat s10.sh 
#!/bin/bash
t_user=aaa
if grep $t_user /etc/passwd
then
        echo "The user $t_user exists on system"
elif ls -d /home/$t_user
then
        echo "The user $t_user does not exist on system."
        echo "However, $t_user has a directory."
fi

[root@linux ~]# sh s10.sh 
ls: cannot access /home/aaa: No such file or directory



[root@linux ~]# cat s101.sh     #elif中嵌套
#!/bin/bash
t_user=aaa
if grep $t_user /etc/passwd
then
        echo "The user $t_user exists on system"
elif ls -d /home/$t_user
then
        echo "The user $t_user does not exist on system."
        echo "However, $t_user has a directory."
else
        echo "The user $t_user does not exist on system."
        echo "And,$t_user does not have a directory."
fi

[root@linux ~]# sh s101.sh 
ls: cannot access /home/aaa: No such file or directory
The user aaa does not exist on system.
And,aaa does not have a directory.


[root@linux ~]# cat s11.sh 
#!/bin/bash
if [ -d $HOME ] && [ -w $HOME/testing ] #-d检查file是否存在且是一个目录,-w可写
then
        echo "The file exists and you can write to it"
else
        echo "I can not write to the file"
fi 

[root@linux ~]# sh s11.sh 
I can not write to the file


[root@linux ~]# cat s12.sh 
#!/bin/bash
value1=10
value2=11
if [ $value1 -gt 5 ]
then 
        echo "The value $value1 is greater than 5"
fi
if [ $value1 -eq $value2 ] 
then
        echo "The values are equal"
else 
        echo "The values are different"
fi

[root@linux ~]# sh s12.sh 
The value 10 is greater than 5
The values are different

Bash练习

1.显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大 小,保存脚本为sys_info.sh

#!/bin/bash
echo "System Device Info"
echo "------------------------"
var1=`hostname`
echo "localhost name:$var1"
var2=`ifconfig | grep 'inet' | grep -v 'inet6' | sed 's/^.*inet//g' | sed 's/netmask.*//g'`
echo "ip address:$var2"
var3=`cat /etc/redhat-release`
echo "Os info:$var3"
var4=`uname -a | cut -d' ' -f 3`
echo "Kernel info:$var4"
var5=`cat /proc/cpuinfo | grep "model name" | cut -d' ' -f 3,4,5,6,7,8` 
echo "cpu info:$var5"
var6=`free -h | grep "Mem" | cut -d' ' -f12`
echo "Memory info:$var6"
var7=`fdisk -l | grep "Disk /dev/sda" | cut -d',' -f 1`
echo "Disk info:$var7"

2.将/etc/目录备份到/tmp下,并以此格式保存bak_etc_yyyy-mm-dd,保存为脚本bak_etc.sh

#!/bin/bash
cp -r /etc /tmp/bak_etc_`date +%F`

3.显示当前硬盘分区中空间利用率大的值,保存脚本为disk_used.sh

#!/bin/bash
disk_usage=`df |tr -s " " | cut -d' ' -f 5 | sort -n | tail -n1`
echo "The max disk used : $disk_usage"

4.显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序,保存脚本为link.sh

#!/bin/bash
netstat -tn | tr -s " " | cut -d " " -f 5| cut -d : -f 1 | sort -nr | uniq -c 

5.计算/etc/passwd文件中的第5个用户和第15用户的ID之和,保存脚本为sum_id.sh

#!/bin/bash
var1=`head -n5 /etc/passwd | tail -n1 | cut -d ':' -f3`
var2=`head -n15 /etc/passwd | tail -n1 | cut -d ':' -f3`
let Num=$var1+$var2
echo $Num

6.统计/etc, /var, /usr目录中共有多少文件,保存脚本为sum.sh

#!/bin/bash
var1=`ls -l /etc/ | wc -l`
echo "/etc/:$var1"
var2=`ls -l /var/ | wc -l`
echo "/var/:$var2"
var3=`ls -l /usr/ | wc -l`
echo "/usr/:$var3"
let sum=$var1+$var2+$var3
echo "sum="$sum

7.接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则输出“该IP地址可访问”;如果不可 ping通,则输出“该IP地址不可访问”,保存脚本为ping.sh

#!/bin/bash
ipaddr='(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2([0-4][0-9]|5[0-5]))\>\.){3}\<([0-9]|[1-9][0-9]|1[0-5][1-9]|2([0-4][0-9]|25[0-5]))\>'
    read -p "please input a IPV4 addr: " ipv4
    if [[ $ipv4 =~ $ipaddr ]];then
        ping $ipv4 -c 4 && echo "这个IP可以正常访问"||echo "这个IP不能访问"
    else
        echo "请输入正确的网址"
        exit
    fi

猜你喜欢

转载自blog.csdn.net/QQ1006207580/article/details/83018803