Linux 笔记 - 第十二章 Shell 脚本

博客地址:http://www.moonxy.com

一、前言

常见的编程语言分为两类:一类是编译型语言,如:C、C++ 和 Java等,它们远行前要经过编译器的编译。另一类是解释型语言,不需要编译,执行时,需要使用解释器一行一行地解释执行,如:awk、perl、python 和 shell 等。

Shell 是一种脚本语言,属于上面提到的第二类语言,就必须有对应的解释器来执行这些脚本,最常见的脚本解释器是:bash。

在编写 Shell 脚本时,我们不仅会用到很多的 Linux 命令、正则表达式、管道符、数据流重定向等语法规则,还需要把内部功能模块化后通过逻辑语句进行处理,最终形成常见的 Shell 脚本。

1.1 查看系统支持的 Shell 种类

Linux 的 Shell 种类众多,常见的有:
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)

可以通过查看 /etc/shells,知道当前系统所支持的所有 shell 类型及路径,如下:

[[email protected] ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
……

Bourn Shell 是最早流行起来的一个 Shell 版本,其创始人是 Steven Bourn,为了纪念他而将其命名为 Bourn Shell,简称 sh。RedHat 系列的 Linux 发行版默认也安装了 Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。

1.2 查看当前用户使用的 Shell 种类

可以通过执行 echo $SHELL 查看,如下:

[[email protected] ~]# echo $SHELL
/bin/bash

或者查看 /etc/passwd,以查看 root 用户的 Shell 类型为例,如下:

[[email protected] ~]# cat /etc/passwd | grep ^root
root:x:0:0:root:/root:/bin/bash

最后一个:号后显示的字段即为 root 用户的登录 shell 类型,此处为 bash。

也可以直接输入命令 echo $0 查看,但需要注意的是并不是所有的 Shell 都支持,如下:

[[email protected] ~]# echo $0
-bash

当然也可以在当前环境变量中查看,如下:

[[email protected] ~]# env | grep SHELL
SHELL=/bin/bash

其实,查看当前用户 Shell 种类的方法还有很多。

1.3 查看 Shell 版本

在获得当前使用的 shell 的类型后,用户可以直接使用 shell 相关的命令参数获取其版本号,一般都可以使用 --version 参数来获取 shell 的版本号,如下:

[[email protected] ~]# bash --version
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

二、常用 Shell 操作

2.1 命令 date

date 命令的常用的格式化选项:

date +%Y:表示以四位数字格式打印年份;

[[email protected] ~]# date +%Y
2018

date +%y:表示以两位数字格式打印年份;

[[email protected] ~]# date +%y
18

date +%m:表示月份;

[[email protected] ~]# date +%m
04

date +%d:表示日期;

[[email protected] ~]# date +%d
14

date +%H:表示小时;

[[email protected] ~]# date +%M
13

date +%M:表示分钟;

[[email protected] ~]# date +%M
04

date +%S:表示秒;

[[email protected] ~]# date +%S
46

date +%w:表示星期,如果结果显示 0 则表示周日;

[[email protected] ~]# date +%w
6

date +%F:表示年月日;

[[email protected] ~]# date +%F
2018-04-14

date +%T:表示时分秒;

[[email protected] ~]# date +%T
14:08:57

date +"%Y-%m-%d %H:%M:%S",显示如下:

[[email protected] ~]# date +"%Y-%m-%d %H:%M:%S"
2018-04-14 14:10:43

date +"%F %T",显示和上面相同。

有时候会用到前一天的日期,如下:

[[email protected] ~]# date -d "-1 day" +"%d"
13

或者后一天的日期,如下:

[[email protected] ~]# date -d "+1 day" +"%d"
15

同理可以设置小时,分钟等。

2.2 数学运算

数学运算的时候要用 [ ] 括起来,并且前面要加符号 $

[[email protected] ~]# a=2;b=3
[[email protected] ~]# ab=$[$a+$b]
[[email protected] ~]# echo $ab
5

定义变量的格式是:

变量名=变量值

定义之后引用该变量时要加上符号 $,如下:

$ab

如果变量的值是 shell  命令,则需要加反引号,它的作用是将引号中的字符串当成 shell 命令来执行。

2.3 和用户交互

read 命令用于和用户交互,它把用户输入的字符串作为变量值。如下:

[[email protected] shelltest]# cat readtest.sh
#!/bin/bash
## This Shell script is used for testing read
read -p "Please input a number:" n
echo $n

[[email protected] shelltest]# ./readtest.sh
Please input a number:5
5

也可添加 -t 选项,设置 3 秒后退出,如下:

read -t 3 -p "Please input a number:" n

2.4 Shell 脚本预设的特殊变量

$* 和 [email protected] 的区别为: $* 和 [email protected] 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"[email protected]" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。

$? 可以获取上一个命令的退出状态。所谓退出状态,就是上一个命令执行后的返回结果。退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。

2.5 转义字符

在 echo 中可以用于的转义字符有:

2.6 Shell 中的引号

Shell 中的引号主要有单引号双引号反引号

单引号

单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;

单引号字串中不能出现单引号(对单引号使用转义符后也不行)。

双引号

双引号里可以有变量;

双引号里可以出现转义字符。

反引号

反引号中的字符串当成 shell 命令来执行。

得到文件名,使用 basename,如下:

[[email protected] shelltest]# basename /root/linux/shelltest/fortest.sh
fortest.sh

得到目录名,使用 dirname,如下:

[[email protected] shelltest]# dirname /root/linux/shelltest/fortest.sh
/root/linux/shelltest

2.7 执行 Shell

有两种方式可以执行 Shell,如下:

第一种:

sh filename.sh

第二种:

./filename.sh(需要有执行权限,所以一般要先授予 x 权限)

三、shell 运算符

3.1 算数运算符

原生 bash 不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr。下面使用 expr 进行;  expr 是一款表达式计算工具,使用它可以完成表达式的求值操作;

3.2 关系运算符

只支持数字,不支持字符串,除非字符串的值是数字。常见的有:

3.3 布尔运算符

-o(--or,也可以用 [ $a -lt 20 ] || [ $b -gt 100 ]),-a(--and,也可以用 [ $a -lt 20 ] && [ $b -gt 100 ])

3.4 字符串运算符

常用的有 -z,判断变量的值是否存在,不存在返回 true,存在则返回 false。

3.5 文件测试运算符

常用的有 -e(--exist,判断文件或目录是否存在),-d(--directory,判断是否目录已经是否存在),-f(--file,判断是否普通文件已经是否存在)

四、Shell 中的流程控制

4.1 if 条件选择

[[email protected] shelltest]# cat iftest.sh
#! /bin/bash
## This shell script is used for testing if
echo "file name $(basename $0)"
echo "Hello $1"
echo "Hello $*"
echo "Args count: $#"
argscount=$#
if [ $argscount -eq 3 ];
then
echo ‘args count is correct‘
elif [ $argscount -gt 3 ];
then
echo ‘args count is more than 3‘
else
echo ‘args count is less than 3‘
fi

运行如下:

[[email protected] shelltest]# sh iftest.sh 3 5 a
file name iftest.sh
Hello 3
Hello 3 5 a
Args count: 3
args count is correct
[[email protected] shelltest]# sh iftest.sh 3 5
file name iftest.sh
Hello 3
Hello 3 5
Args count: 2
args count is less than 3
[[email protected] shelltest]# sh iftest.sh 3 5 a b
file name iftest.sh
Hello 3
Hello 3 5 a b
Args count: 4
args count is more than 3

4.2 case 条件选择

[[email protected] shelltest]# cat casetest.sh
#!/bin/bash
## This shell script is used for testing case
read -p "Input a number:" n
a=$[$n%2]
case $a in
1)
echo "The number is odd."
;;
0)
echo "The number is even."
;;
*)
echo "It‘s not a number!"
;;
esac

运行如下:

[[email protected] shelltest]# sh casetest.sh
Input a number:4
The number is even.
[[email protected] shelltest]# sh casetest.sh
Input a number:5
The number is odd.

4.3 while 循环

[[email protected] shelltest]# cat whiletest.sh
#!/bin/bash
## This shell script is used for testing while
a=5
while [ "$a" -ge "1" ]; do
echo $a
a=$[$a-1]
done

运行如下:

[[email protected] shelltest]# sh whiletest.sh
5
4
3
2
1

4.4 for 循环

[[email protected] shelltest]# cat fortest.sh
#!/bin/bash
## This shell script is used for testing for

for file in `ls /root/linux/shelltest`;
do
ls -ld /root/linux/shelltest/$file
done

运行如下:

[[email protected] shelltest]# sh fortest.sh
-rwxr-xr-x 1 root root 233 Apr 14 17:33 /root/linux/shelltest/casetest.sh
-rw-r--r-- 1 root root 18 Apr 13 20:49 /root/linux/shelltest/field.properties
-rwxr-xr-x 1 root root 141 Apr 14 17:40 /root/linux/shelltest/fortest.sh
-rwxr-xr-x 1 root root 211 Apr 13 20:48 /root/linux/shelltest/funcomp.sh
-rwxr-xr-x 1 root root 235 Apr 13 20:47 /root/linux/shelltest/funtest.sh
-rwxr-xr-x 1 root root 321 Apr 13 20:46 /root/linux/shelltest/iftest.sh
-rwxr-xr-x 1 root root 101 Apr 14 14:37 /root/linux/shelltest/readtest.sh
-rwxr-xr-x 1 root root 113 Apr 13 20:46 /root/linux/shelltest/whiletest.sh

4.5 引入其他 Shell

方法一:使用 .

#!/bin/bash
. firstshell.sh
echo ‘your are in second file‘

方法二:使用 source

#!/bin/bash
source firstshell.sh
echo ‘your are in second file‘

4.6 Shell 中的中断和继续

break,用于循环中,表示退出该层循环到上一层;

continue,用于循环中,表示结束本次循环,开始下次循环;

exit,用在任何地方,表示退出 shell 脚本;

return,用在函数中,表示返回,退出函数;

这几个命令与 C、Java 等语言中对应的关键字的作用一样。

原文地址:https://www.cnblogs.com/cnjavahome/p/8831612.html

时间: 2024-10-14 11:23:00

Linux 笔记 - 第十二章 Shell 脚本的相关文章

第十二章 Shell脚本编写及常见面试题(一)

注意事项 1)开头加解释器:#!/bin/bash 2)语法缩进,使用四个空格:多加注释说明. 3)命名建议规则:变量名大写.局部变量小写,函数名小写,名字体现出实际作用. 4)默认变量是全局的,在函数中变量local指定为局部变量,避免污染其他作用域. 5)有两个命令能帮助我调试脚本:set -e 遇到执行非0时退出脚本,set-x 打印执行过程. 6)写脚本一定先测试再到生产上. 12.1 获取随机字符串或数字 获取随机8位字符串: 方法1: # echo $RANDOM |md5sum |

第十二章 Shell脚本编写及常见面试题(二)

本章目录: 12.11 屏蔽网站访问频繁的IP 1)屏蔽每分钟访问超过200的IP 方法1:以Nginx日志作为测试 DATE=$(date +%d/%b/%Y:%H:%M) ABNORMAL_IP=$(tail -n5000 access.log |grep $DATE |awk '{a[$1]++}END{for(i in a)if(a[i]>100)print i}') #先tail防止文件过大,读取慢,数字可调整每分钟最大的访问量.awk不能直接过滤日志,因为包含特殊字符. for IP

第十二章 Shell脚本编写及常见面试题(三)

本章目录: 12.21 FTP下载文件 #!/bin/bash if [ $# -ne 1 ]; then     echo "Usage: $0 filename" fi dir=$(dirname $1) file=$(basename $1) ftp -n -v << EOF   # -n 自动登录 open 192.168.1.10 user admin adminpass binary   # 设置ftp传输模式为二进制,避免MD5值不同或.tar.gz压缩包格式

linux学习笔记-第十二课-Shell脚本之正则表达式(一)

一.grep,egrep,fgrep 1)grep 格式:grep [选项] [模式] [文件名] 常用选项:-n:显示行号和匹配的行 -v:反向匹配 -c:不显示匹配的行,只显示匹配的行数 -i:忽略大小写 -r:递归搜索 -E:支持扩展正则表达式 -P:支持Perl正则表达式 -F:不支持正则表达式,将模式按字面意义匹配 示例: grep示例 说明 grep '\<Tom>\' file 显示包含单词Tom的行 grep 'Tom Jerry' file 显示包含'Tom Jerry'的行

Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 这一章很多,但是很有趣,也是这书的最后一章知识点了,我现在还在考虑要不要写这个拼图和2048的案例,在此之前,我们先来玩玩Android5.X的新特性吧!

Java学习笔记—第十二章 Java网络编程入门

第十二章  Java网络编程入门 Java提供的三大类网络功能: (1)URL和URLConnection:三大类中最高级的一种,通过URL网络资源表达方式,可以很容易确定网络上数据的位置.利用URL的表示和建立,Java程序可以直接读入网络上所放的数据,或把自己的数据传送到网络的另一端. (2)Socket:又称"套接字",用于描述IP地址和端口(在Internet中,网络中的每台主机都有一个唯一的IP地址,而每台主机又通过提供多个不同端口来提供多种服务).在客户/服务器网络中,当客

[CSAPP笔记][第十二章并发编程]

第十二章 并发编程 如果逻辑控制流在时间上是重叠,那么它们就是并发的(concurrent).这种常见的现象称为并发(concurrency). 硬件异常处理程序,进程和Unix信号处理程序都是大家熟悉的例子. 我们主要将并发看做是一种操作系统内核用来运行多个应用程序的机制. 但是,并发不仅仅局限于内核.它也可以在应用程序中扮演重要的角色. 例如 Unix信号处理程序如何允许应用响应异步事件 例如:用户键入ctrl-c 程序访问虚拟存储器的一个未定义的区域 其他情况 访问慢速I/O设备 当一个应

《APUE》读书笔记第十二章-线程控制

本章中,主要是介绍控制线程行为方面的内容,同时介绍了在同一进程中的多个线程之间如何保持数据的私有性以及基于进程的系统调用如何与线程进行交互. 一.线程属性 我们在创建线程的时候可以通过修改pthread_attr_t结构的值来修改线程的属性,将这些属性与创建的线程联系起来.调用pthread_attr_init以后,pthread_attr_t结构所包含的内容就是操作系统实现支持的线程所有属性. #include <pthread.h> int pthread_attr_init(pthrea

Linux笔记(十二) - 服务管理

(1)服务的分类1.rpm包默认安装的服务 a.独立的服务 b.基于xinetd服务2.源码包的服务查询已安装的服务1.rpm包安装的服务 查看服务(0-6运行级别下的)自启动状态,可以看到所有rpm包安装的服务:chkconfig --list2.源码包安装的服务 查看服务安装位置,一般是/usr/local/下rpm安装服务与源码包安装服务的区别位置不同: rpm安装在默认位置 源码包安装在指定位置,一般是/usr/local/下(1)rpm服务的管理rpm安装的位置/etc/init.d/