Shell脚本基础知识

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell脚本基础知识相关的知识,希望对你有一定的参考价值。

博文目录
一、Shell脚本基础
二、重定向与管道操作
三、使用Shell变量

一、Shell脚本基础

Linux系统中的Shell脚本是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了一个“命令解释器”的角色,负责接收用户输入的操作命令并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。

1、简单编写Shell脚本

[root@centos01 ~]# vim aaa.sh    <!--新建aaa.sh文件-->
#!/bin/bash
#Description E-Mail:2807489749@qq.com BY:LYX
cd /boot/
echo "显示当前目录:"
pwd
echo "查看以vml开头的文件:"
ls -lh vml*
[root@centos01 ~]# chmod +x aaa.sh     <!--添加可执行权限-->

上述aaa.sh脚本文件中,第一行“#!/bin/bash”是一行特殊的脚本声明,表示此行以后的语句通过/bin/bash程序来解释执行;其他以“#”开头的语句表示注释信息;echo命令用于输出字符串,以使脚本的输出信息更容易读懂。上述配置包括三条命令:cd /boot/、pwd、ls -lh vml*。执行此脚本文件后,输出结果与依次单独执行这三条命令是相同的,从而实现了“批量处理”的自动化过程。

通过“./aaa.sh”的方式执行脚本,执行之前必须授权于文件的X权限。

[root@centos01 ~]# ./aaa.sh    <!--运行脚本文件-->
/boot
-rwxr-xr-x. 1 root root 5.7M 10月 23 22:35 vmlinuz-0-rescue-2b580d1a2e8348b8aa9f78be11137b41
-rwxr-xr-x. 1 root root 5.7M 8月  23 2017 vmlinuz-3.10.0-693.el7.x86_64
[root@centos01 ~]# source aaa.sh  <!--通过source来解释脚本-->
[root@centos01 ~]# sh aaa.sh     <!--通过/bin/sh来解释脚本-->

二、重定向与管道操作

1、重定向输出

表示将命令的正常输出结果保存到指定的文件中,并覆盖文件中的原有内容,若文件不存在,则会新建一个文件使用 “>”操作符号。

表示将命令的正常输出结果追加到指定的文件中sh使用“>>”操作符号。

举个例子:

[root@centos01 ~]# echo "aaa"  <!--数据输出到显示器上显示-->
aaa
[root@centos01 ~]# echo "aaa" > 1.txt    <!--将数据输出到文件中-->
[root@centos01 ~]# cat 1.txt      <!--查看文件中数据-->
aaa
[root@centos01 ~]# echo "bbb" >> 1.txt      <!--将数据追加输出到1.txt文件中-->
[root@centos01 ~]# cat 1.txt         <!--查看文件-->
aaa
bbb

2、重定向输入

重定向输入指的是将命令中接收输入的途径由默认的键盘改为指定的文件,而不是等待从键盘输入。重定向输入使用“<”操作符。

举个例子:
使用passwd命令为用户设置密码时,每次都必须根据提示输入两次密码字串,非常繁琐,若改用重定向输入将可以省略交互式的过程,而自动完成密码设置。

[root@centos01 ~]# useradd bob  <!--创建bob用户-->
[root@centos01 ~]# vim password.txt     <!--添加初始密码串-->
pwd@123                    <!--密码为pwd@123-->
[root@centos01 ~]# passwd --stdin bob < password.txt      <!--从password.txt文件中取密码-->
更改用户 bob 的密码 。
passwd:所有的身份验证令牌已经成功更新。

3、错误重定向

错误重定向指的是将执行命令过程中出现的错误信息(如选项或参数错误等)保存到指定的文件,而不是直接显示在屏幕上。错误重定向使用 “2>”操作符,其中“2”是指错误文件的编号(在使用标准输出、标准输入重定向时,实际上省略了1、0编号)。

举个例子:
执行以下操作可以将使用tar命令进行备份时出现的错误信息保存到3.txt文件中。

[root@centos01 ~]# tar jcf /nonedir/etc.tgz /etc/ 2> 3.txt
[root@centos01 ~]# 
[root@centos01 ~]# cat 3.txt
tar: 从成员名中删除开头的“/”
tar (child): /nonedir/etc.tgz:无法 open: 没有那个文件或目录
tar (child): Error is not recoverable: exiting now

使用“2>”操作符时,会像使用“>”操作符一样覆盖目标文件的内容,若要追加内容而不是覆盖文件,则应改用“2>>”操作符。
当命令输出的结果可能即包括标准输出(正常执行)信息,又包括错误输出信息时,可以使用操作符“>” “2>”将两类输出信息分别保存到不同的文件,也可以使用“&>”操作符两两类输出信息保存到同一个文件。
举个例子:

[root@centos01 ~]# vim httpd.sh   <!--新建httpd.sh文件-->
#!/bin/bash
#自动编译安装httpd服务器
cd /usr/src/httpd-2.2.17/
echo "1.配置Apache服务:"
./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --enable-charset-lite --enable-cgi &> /dev/null
echo "2.编译Apache服务:"
make &> /dev/null
echo "3.安装Apache服务:"
make install &> /dev/null
[root@centos01 ~]# chmod +x httpd.sh   <!--添加X权限-->
[root@centos01 ~]# ./httpd.sh     <!--运行脚本文件-->
1.配置Apache服务:
2.编译Apache服务:
3.安装Apache服务:

4、管道操作

管道(pipe)操作为不同命令之间的协同工作提供了一种机制,位于管道符号“|”左侧的命令输出的结果,将作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道。

举个例子:

[root@centos01 ~]# grep "/bin/bash$" /etc/passwd  <!--提取前-->
root:x:0:0:root:/root:/bin/bash
test:x:1000:1000:test:/home/test:/bin/bash
bob:x:1002:1002::/home/bob:/bin/bash
[root@centos01 ~]# grep "/bin/bash$" /etc/passwd | awk -F: ‘{print $1,$7}‘   <!--提取后-->
root /bin/bash
test /bin/bash
bob /bin/bash
[root@centos01 ~]# df -hT     <!--提取之前-->
文件系统       类型      容量  已用  可用 已用% 挂载点
/dev/sda3      xfs        76G  5.2G   71G    7% /
devtmpfs       devtmpfs  474M     0  474M    0% /dev
tmpfs          tmpfs     489M     0  489M    0% /dev/shm
tmpfs          tmpfs     489M  6.9M  482M    2% /run
tmpfs          tmpfs     489M     0  489M    0% /sys/fs/cgroup
/dev/sda1      xfs       197M  136M   61M   70% /boot
tmpfs          tmpfs      98M     0   98M    0% /run/user/0
/dev/sr0       iso9660   664M  664M     0  100% /mnt
[root@centos01 ~]# df -hT | grep "/$" |awk ‘{print $6}‘   <!--提取之后其中grep “/$”表示提取以“/”结尾的行-->
7%

上述中awk命令的作用是以冒号“:”作为分隔,输出第1个,第7个区域的字符串。其中的“-F”部分用来指定分割符号(未指定时,默认以空格或制表符分隔)。

三、使用Shell变量

各种Shell环境中都使用到了“变量”的概念。Shell变量用来存放系统和用户需要使用的特定参数(值),而且这些参数可以根据用户的设定或系统环境的变化而相应变化。通过使用变量,Shell程序能够提供更加灵活的功能,适应性更强。
常见Shell变量的类型包括自定义变量、环境变量、位置变量、预定义变量。

1、自定义变量

自定义变量是由系统用户自己定义的变量,只在用户自己的Shell环境中有效,因此又称为本地变量。在编写Shell脚本程序时,通常会设置一些特定的自定义变量,以适应程序执行过程中的各种变化,满足不同的需求。

1)定义新的变量

定义变量的基本格式为“变量名=变量值”,等号两边没有空格。变量名称需以字母或下划线开头,名称中不要包含特殊字符(如+、-、*、/、?、%、&、#等)。

[root@centos01 ~]# li=python
[root@centos01 ~]# version=2.7.13

2)查看和引用变量的值

通过在变量名称前添加前导符号“$”,可以引用一个变量的值。使用echo命令可以查看变量,可以在一条echo命令中同时查看多个变量值。

[root@centos01 ~]# echo $li
python
[root@centos01 ~]# echo $version
2.7.13
[root@centos01 ~]# echo $li $version
python 2.7.13

3)变量赋值的特殊操作

在等号“=”后边直接指定变量内容是为变量赋值的最基本方法,除此之外,还有一些特殊的赋值操作,可以更灵活地位变量赋值,以便适用于各种复杂的管理任务。

①双引号(" ")

[root@centos01 ~]# PYTHON=python 2.7.13  <!--错误赋值-->
bash: 2.7.13: 未找到命令...
[root@centos01 ~]# PYTHON="python 2.7.13" <!--正确的赋值-->
[root@centos01 ~]# echo $PYTHON   <!--查看值-->
python 2.7.13

在双引号范围内,使用“$”符号可以引用其他变量的值(变量引用),从而能够直接调用现有变量的值来赋给新的变量。

[root@centos01 ~]# echo $version
2.7.13
[root@centos01 ~]# sqlserver="sqlserver $version" 
                                       <!--以变量的值进行赋值-->
[root@centos01 ~]# echo $sqlserver    <!--查看值-->
sqlserver 2.7.13

②单引号(‘ ‘)

当要赋值的内容中包含$、“、等具有特殊含义的字符时,应使用单引号括起来。在单引号的范围内,将无法引用其他变量的值,任何字符均作为普通字符看待。

[root@centos01 ~]# sqlserver=‘sqlserver $version‘  <!--$符号不能再引用变量-->
[root@centos01 ~]# echo $sqlserver      <!--原样输出字符串-->
sqlserver $version

③反撇号(`)

反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。反撇号括起来的范围必须能够执行的命令行,否则将会出错。

[root@centos01 ~]# ls -lh `which useradd`
-rwxr-x---. 1 root root 116K 11月  6 2016 /usr/sbin/useradd

上述操作相当于连续执行了两条命令——先通过which useradd命令查找出useradd命令的程序位置,然后根据查找结果列出文件属性。执行过程中,会用which useradd命令的输出结果替换整个反撇号范围。

④read命令

除了上述赋值操作以外,还可以使用bash的内置命令read来给变量赋值。read命令用来提示用户输入信息,从而实现简单的交互过程。执行时将从标准输入设备(键盘)读入一行内容,并以空格为分隔符,将读入的各字段依次赋值给指定的变量(多余的内容赋值给最后一个变量)。若指定的变量只有一个,则将整行内容赋值给此变量。

[root@centos01 ~]# read -p "输入需要的内容:" insert
输入需要的内容:您好!  <!--将您好!赋值给变量insert-->
[root@centos01 ~]# echo $insert
您好!

4)设置变量的作用范围

默认情况下,新定义的变量只在当前的Shell环境中有效,因此称为局部变量。当进入子程序或新的子Shell环境时,局部变量将无法再使用。例如,直接执行Bash进入一个新的子Shell脚本后,将无法引用父级Shell环境中定义的li、version等变量。

[root@centos01 ~]# echo "$li $version"   <!--查看当前定义的变量值-->
python 2.7.13
[root@centos01 ~]# bash            <!--进入子shell环境-->
[root@centos01 ~]# echo "$li $version"        <!--无法调用父shell环境中的变量-->
[root@centos01 ~]# exit        <!--返回原有的shell环境-->
exit
[root@centos01 ~]# echo "$li $version"   <!--查看当前定义的变量值-->
[root@centos01 ~]# export li version     <!--设置为全局变量-->
[root@centos01 ~]# bash          <!--进入子shell环境-->
[root@centos01 ~]# echo "$li $version" <!--可以调用父shell的全局变量-->
python 2.7.13
[root@centos01 ~]# exit     <!--返回原有的shell环境-->
exit

5)数值变量的运算

Shell变量的数值运算多用于脚本程序的过程控制(如循环次数、使用量比较等)再Bash shell环境中,只能进行简单的证书运算,不支持小数运算。整数值的运算主要通过内部命令expr进行,基本格式如下:

expr 变量1 运算符 变量2 [运算符 变量3]...

其中,变量1、变量2......对应为需要计算的数值变量(需要以“$”符号调用),常用的几种运算符如下所述
+:加法运算;
-:减法运算;
*:乘法运算;注意不能仅使用“*”符号,否则将被当成文件通配符;
/:除法运算;
%:求模运算,又称为取余运算,用来计算数值相除后的余数;

举个例子:

[root@centos01 ~]# x=35
[root@centos01 ~]# y=16
[root@centos01 ~]# expr $x + $y
51
[root@centos01 ~]# expr $x - $y
19
[root@centos01 ~]# expr $x * $y
560
[root@centos01 ~]# expr $x / $y
2
[root@centos01 ~]# expr $x % $y
3

2、特殊的shell变量

1)环境变量:

使用命令“env”可以查看到当前工作环境下的环境变量。环境变量的值由Linux系统自动维护,会随着用户状态的改变而改变。
其中PATH变量用于设置可执行程序的默认搜索路径,如将root目录添加到默认搜索路径:PATH="$PATH:/root"如果找不到则会提示“command not found”

环境变量的全局配置文件为:/etc/profile,在此文件中定义的变量作用于所有用户。

用户独立配置未见位于:~/.bash_profile

修改变量文件后,须使用source命令重新读取加载或重启才会生效。

2)位置变量:

位置变量也称位置参数,在命令 “ls -lh /boot” 中,ls的位置变量为$0,-lh的位置变量为$1,/boot的位置变量为$2。以此类推。

3)预定义变量:

预定义变量是由bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。预定义变量使用“$”符号和另一个符号组合表示,经常用的几个预定义变量含义如下:

  • $#:表示命令行中位置参数的个数。

  • $*:表示所有位置参数的内容。

  • $?:表示前一条命令执行后返回的状态,返回0表示执行正确,返回任何非0的数值表示执行出现异常。

  • $0:表示当前执行的脚本或程序的名称。

—————— 本文至此结束,感谢阅读 ——————

以上是关于Shell脚本基础知识的主要内容,如果未能解决你的问题,请参考以下文章

shell 脚本 片段

用于确保在任何给定时间仅运行一个 shell 脚本的 shell 片段 [重复]

常用python日期日志获取内容循环的代码片段

shell脚本引用expect

Shell脚本切割日志

shell脚本基础