加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

构建脚本

发布时间:2020-12-15 09:11:13 所属栏目:安全 来源:网络整理
导读:构建脚本 10.1 使用多个命令 shell脚本的关键在于输入多个命令,并处理命令的结果,即使有可能将一个命令的结果传给另一个命令。 如果两个命令一起运行,可在同一提示行输入它们,用分号分隔开。 命令列表:在命令行中输入 date;who 命令 进程列表:在命令行

构建脚本

10.1 使用多个命令

shell脚本的关键在于输入多个命令,并处理命令的结果,即使有可能将一个命令的结果传给另一个命令。

如果两个命令一起运行,可在同一提示行输入它们,用分号分隔开。

  • 命令列表:在命令行中输入 date;who 命令
  • 进程列表:在命令行中输入(date;who) 命令
[root@centos1 ~]# date ; who
Sat Dec  9 10:39:17 CST 2017
root     pts/0        2017-12-09 10:01 (192.168.20.224)

10.2 创建shell脚本文件

要将shell命令放到一个文本文件中。在创建shell脚本文件时,必须在文件的第一行制动要使用的shell 其格式为:

#!/bin/bash

在通常的shell脚本里, 井号 # 用作注释行。 shell脚本 注释行是不被shell执行的。然而,shell脚本文件的第一行是个特例,井号后接叹号 告诉shell用哪个shell来运行脚本。

在指定了shell之后可在文件的每行输入命令,然后加一个回车符。之前提到过,注释可用井号添加 。

以# 号 开头的行都不会被shell处理 出了以(#!开头的第一行) 。

chmod u+x abc

10.3 显示消息

在bash脚本中可以使用echo 命令打印输出:

[root@centos1 ~]# echo This is a test
This is a test

如果在字符串中出现引号的话就可能比较麻烦,echo 命令可用单引号或使用双引号来将文本字符串圈起来。如果你再文本中使用一种引号,二用另外一种来将字符串圈起来:

[root@centos1 ~]# echo "Lets's go"
Lets's go
[root@centos1 ~]# cat abc 
#!/bin/bash
echo "The time and date are:"
date;
who
[root@centos1 ~]# ./abc 
The time and date are:
Sat Dec  9 11:05:23 CST 2017
root     pts/0        2017-12-09 10:01 (192.168.20.224)

如果想在同一行显示一个文本字符串作为命令输出:可以使用echo -n 参数,只要将第一个echo语句改为这样就行。

[root@centos1 ~]# cat abc
#!/bin/bash
echo -n "The time and date are:"
date;
who
[root@centos1 ~]# ./abc 
The time and date are:Sat Dec  9 11:07:16 CST 2017
root     pts/0        2017-12-09 10:01 (192.168.20.224)

完美! echo 命令是shell脚本中桶用户交互的重要工具。

10.4.1 环境变量

[root@centos1 bash_dir]# cat test2 
#!/bin/bash
echo "User info for userid : $USER"
echo UID : $UID
echo HOME : $HOME
[root@centos1 bash_dir]# ./test2 
User info for userid : root
UID : 0
HOME : /root

注意,echo命令中的环境变量会在银杏是替换成当前值。还有在第一个字符串中我们可以将$USER系统变量放置到双引号中,而shell依然能够知道我们的意图。采用这种方式也有一个问题,看看下面这个例子会怎样。

[root@centos1 bash_dir]# echo "The $15"
The 5

显然这不是我们想要的,要显示美元符,你必须在前面防止一个反斜线:

[root@centos1 bash_dir]# echo "The $15"
The $15

反斜线允许shell脚本将美元符解释为实际的美元符,而不是变量。下一节将会介绍如何在脚本中创建自己的变量。

你可能还见过${variable} 形式引用的变量。变量名两侧额外的花括号通常用来帮助识别美元符后的变量名。

10.4.2 用户变量

除了环境变量,shell脚本还允许在脚本定义和使用自己的变量,定义变量允许临时存储数据并在整个脚本中使用,从而使shell脚本看起来更像计算机程序。

用户变量可以是任何不超过20个字母,数字或 下划线的文本字符串。 用户变量区分大小写,所以变量Var1和变量var1 是不同的。

值通过等号赋给用户变量。在变量、等号和值之间不能出现空格

  • var1=10
  • var2=-57
  • var3=testing
  • var4="Still more testing"

shell脚本会自动决定变量值的数据类型。在shell脚本的整个生命周期里,shell脚本中定义的变量会一致保持着它们的值,但在shell脚本完成时删除掉。

[root@centos1 bash_dir]# cat test3
#!/bin/bash
days=10
guest="Katie"
echo $guest "checked in $days"
[root@centos1 bash_dir]# ./test3
Katie checked in 10

10.4.3 反引号

shell脚本中最有用的特性之一就是反引号(`) .在shell脚本之外很少用到它,反引号允许你将shell命令的输出赋给变量。

你必须用反引号把这个命令行命令圈起来:

[root@centos1 bash_dir]# testing=`date`; echo $testing
Sat Dec 9 11:37:43 CST 2017
[root@centos1 bash_dir]# echo $testing
Sat Dec 9 11:37:43 CST 2017
[root@centos1 bash_dir]# (test=`date`; echo $test)
Sat Dec 9 11:38:31 CST 2017
[root@centos1 bash_dir]# echo $test

[root@centos1 bash_dir]#
  1. 第一个定义命令列表,是在当前session中定义的用户变量
  2. 第二个是定义的进程列表,新创建一个进程,在进程里定义用户变量,出了该进程范围则输出为空

在脚本中通过反引号获得当前日期用用它来生成唯一文件名:

[root@centos1 bash_dir]# cat var1 
#!/bin/bash
today=`date +%y%m%d`
ls /usr/bin -al > log.$today
[root@centos1 bash_dir]# ls
abc  log.171209  test2  test3  var1

10.5 重定向输入和输出

有些时候你想要保存某个命令的输出而非在显示器上显示它。 bash shell提供了一些不同的操作符来将某个命令的输出重定向到另一个位置(比如文件)。重定向可以通过将某个文件重定向到某个命令上来用在输入上, 也可以用在输出上。

10.5.1 输出重定向

重定向最基本的类型是将命令的输出发到一个文件中。 bash shell采用大于号(>) 来完成这个功能

command > outputfile

之前显示器上出现的命令的输出会被保存到指定的输出文件中。

[root@centos1 bash_dir]# date > test3
[root@centos1 bash_dir]# cat test3 
Sat Dec  9 11:51:58 CST 2017

重定向操作符创建了一个文件test3(通过默认的umusk设置), 如果输出文件已存在了,则这个重定向操作符会用新的文件数据覆盖已存在的文件

有时需要将命令的输出追加到已有文件上 可以用双大于号(>>) 来追加数据:如果文件不存在则创建。

date >> test4

10.5.2 输入重定向

输入重定向和输出重定向正好相反。输入重定向将文件的内容重定向到命令,而非将命令的输出重定向到文件。

输入重定向符号是小于号(<) :

command < inputfile

[root@centos1 bash_dir]# wc test2
 4 16 82 test2
[root@centos1 bash_dir]# wc < test2
 4 16 82

wc 命令提供了对数据中文本的计数。 默认情况下,它会输出3个值:

  • 文本行数
  • 文本词数
  • 文本的字节数

通过将文本文件重定向到 wc 命令。

还有一种输入重定向的方法,成为内联输入重定向。 这种方法允许你在命令行,而不是在文件指定输入重定向的数据。内联输入重定向符号是双小于号(<<)。除了这个符号,你必须指定一个文本标记来划分要输入数据的开始和结尾。 你可以用任何字符串的值来作为文本标记。但在数据的开始和结尾必须一致:

command << marker
data
marker

在这个命令行上使用内敛输入重定向时,shell会用PS2 环境变量中定义的次提示符,来提示输入数据。下面是使用它的情况:

[root@centos1 bash_dir]# wc << EOF
> aksjfd
> kajsdl
> lakjsdlfl
> askdfl
> lskfks
> s
> lksdf
> EOF
 7  7 46
[root@centos1 bash_dir]# wc << aa
> ksjdfk
> ksdjfk
> iwerui
> aa
 3  3 21

次提示符会一直提示输入更多的数据,知道你输入了作为文本标记的那个字符串值。wc 命令会对内联输入重定向提供的数据执行 行 词 和字节计数。

10.6 管道

有时你需要发送某个命令的输出作为另一个命令的输入。可以用重定向,会有些笨拙

rpm -qa > rpm.list
sort < rpm.list

先输出linux系统上安装文件的列表到rpm.list文件中。

然后排序文件中的内容。

类似于反引号(`) 管道的符号在 shell编程之外也很少用到。管道放在命令键,将一个命令的输出重定向到另一个上: command1 | command2

不要以为管道连接会一个一个地运行,Linux系统实际上会同时运行这两个命令,在系统内部将它们连接起来。在第一个命令产生输出的同时,输出会被立即送到第二个命令。传输数据不会用到任何中间文件或缓冲区。

[root@centos1 bash_dir]# rpm -qa | sort

可以在一条命令中使用任意多条管道,可以继续将命令的输入通过管道传给其他命令来简化操作。

[root@centos1 bash_dir]# rpm -qa | sort | more

10.7 执行数学运算

在shell脚本中有两种痛经进行数学运算操作

10.7.1 expr命令

可以处理数学表达式,但是特别笨拙。

var1=`expr 1/2`

10.7.2 使用方括号

bash shell 为了保持跟Boume shell的兼容而包含了expr命令。但它同样也提供了一个执行数学表达式的更简单的方法。 bash中 将一个数学运算结果赋给某个变量时,你可以用美元符和 方括号($[operation]) 将数学表达式圈起来:

[root@centos1 bash_dir]# (var=$[1 + 5];echo $var)
6
[root@centos1 bash_dir]# (var=$[1 + 5];echo $var ; var2=$[$var * 2]; echo $var2)
6
12

同样,注意在使用方括号来计算公式时,不用担心shell会误解乘号或其他符号,shell知道它不是通配符,因为它在方括号内。

bash shell数学运算只支持整数,如果要进行任何数学运算,这是一个巨大的限制。

10.7.3 浮点解决方案

使用内建的bash计算器,称作bc。

1.bc的基本用法

bash计算器其实是允许在命令行输入浮点表达式、解释表达式、计算并返回结果的一种编程语言。bash计算器能够识别:

  • 数字(整数和浮点数)
  • 变量(简单变量和数组)
  • 注释(以# 开始IDE行或 C语言中的/* */对)
  • 表达式
  • 编程语句(例如if-then语句)
  • 函数

你可以在shell提示符下通过bc命令访问bash 计算器:

[root@centos1 bash_dir]# bc
bc 1.06.95
Copyright 1991-1994,1997,1998,2000,2004,2006 Free Software Foundation,Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
12 * 54
648
12 * 5.4
64.8
3.156 * (3+5)
25.248
quit

浮点运算是由一个内建的成为scale的变量控制的。你必须将这个字设置为结果里你想要的小数后的位数,否则你不会得到想要的结果的:

[root@centos1 bash_dir]# bc -q
3.44/5
0
scale=4
3.44/5
.6880
quit
[root@centos1 bash_dir]#

scale变量默认值是0 , 在scale值被设置前,bash计算器提供的答案没有小数点后的位置。在将其设置为4之后,bash计算器显示的答案有4位小数。-q命令行参数会将bash计算器输出的很长的欢迎条屏蔽掉。

出了普通数字,bash计算器还能支持变量:

[root@centos1 bash_dir]# bc -q
var1=10
var*4
0
var1*4
40
var2=var1/5
print var2
2
quit
[root@centos1 bash_dir]#

2.在脚本中使用bc

可以使用反引号来运行bc命令并将输出赋给一个变量。

variable=`echo "options;expression" | bc`

[root@centos1 bash_dir]# (variable=`echo "scale=4;3.44/5" | bc`; echo $variable)
.6880

这里有个在脚本中使用它的例子:

[root@centos1 bash_dir]# cat calculate 
#!/bin/bash
var1=`echo "scale=4;3.44/5" | bc`
echo "The answer is $var1"
[root@centos1 bash_dir]# ./calculate 
The answer is .6880
[root@centos1 bash_dir]#

这个例子在scale变量设置成了四位小苏,并未表达式指定了特定的运算。

[root@centos1 bash_dir]# cat varcalcu 
#!/bin/bash
var1=100
var2=45
var3=`echo "scale=4;$var1/$var2" | bc`
echo "The answer for this is $var3"
[root@centos1 bash_dir]# ./varcalcu 
The answer for this is 2.2222
[root@centos1 bash_dir]#

脚本中定义了两个变量,它们都可以用在表达式中发送给bc命令。使用美元符来表示变量的值而不是变量自身,这个脚本输出如下:

这个方法适用于较短的运算,但有时你会更多地和你自己的数字打交道。如果你有很多运算,在同一个命令行中列出多个表达式就会有点麻烦。

针对这个问题有个解决办法。bc命令能够识别输入重定向,允许你将一个文件重定向到bc命令来处理。然而这样也叫人困惑,因为你必须将表达式存储到文件中。

最好的办法是使用内联输入重定向,允许你直接在控制台重定向数据。在shell脚本中,你可以将输出赋给一个变量:

variable=`bc << EOF
options
statements
expressions
EOF
`

EOF文本 字符串标识了内联重定向数据的开始和结尾。记住仍然需要反引号来将bc命令的输出赋给变量

[root@centos1 bash_dir]# cat eof 
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=`bc << EOF
scale=4
a1=$var1*$var2
b1=$var3*var4
a1+bc
EOF
`
echo "The final answer for this mess is $var5"
[root@centos1 bash_dir]# ./eof 
The final answer for this mess is 456.7882

将每个选项和表达式放在脚本中不同的行中,可以让事情变得更清晰,也更容易阅读和跟进。EOF字符串标识了内联重定向给bc命令数据的起始和结尾。当然,你也要用反引号来标识输出要赋给变量的命令

bash运算器中创建的变量只在bash计算器中有效,不能再shell脚本中使用。

10.8 退出脚本

我们的实例脚本那种总是匆忙结尾,在运行完最后一条命令时,就结束了脚本。这里还有一个更好的结束事情的办法。

shell中运行的每个命令都是使用退出状态码(exit status) 来告诉shell它完成了处理。退出状态码是一个0~255 之间的整数值,在命令结束运行时由命令传给shell,你可以捕获这个值并在脚本中使用。

10.8.1 查看退出状态码

Linux提供了 $? 专属变量来保存上个执行的命令的退出状态码。必须在要查看的命令之后马上查看或使用$?变量。它的值会变成shell中执行的最后一条命令的退出状态码:

[root@centos1 bash_dir]# date
Sat Dec  9 14:57:41 CST 2017
[root@centos1 bash_dir]# echo $?
0
[root@centos1 bash_dir]#
[root@centos1 bash_dir]# sdkjf
-bash: sdkjf: command not found
[root@centos1 bash_dir]# echo $?
127
[root@centos1 bash_dir]#

无效命令会返回一个退出状态码127 。Linux错误退出状态码没有什么标准惯例。但有一些可用的参考,如下

[root@centos1 bash_dir]# date %t
date: invalid date `%t'
[root@centos1 bash_dir]# echo $?
1
[root@centos1 bash_dir]#

10.8.2 exit命令

默认情况下,shell脚本会以脚本中的最优一个命令的退出状态码退出:

[root@centos1 bash_dir]# ./eof 
The final answer for this mess is 456.7882
[root@centos1 bash_dir]# echo $?
0
[root@centos1 bash_dir]#

你可以改变这个来返回你自己的退出状态码。exit命令允许你再脚本结束时指定一个退出状态码:

[root@centos1 bash_dir]# cat test10
#!/bin/bash
var1=20
var2=10
var3=`bc << EOF
$var1+var2
EOF
`
echo "The answer is $var3"
exit 5
[root@centos1 bash_dir]# ./test10
The answer is 20
[root@centos1 bash_dir]# echo $?
5

也可以在exit命令的参数中使用变量

exit $var

需注意使用exit时 参数值最大只能255 。 结果值是指定的数被256除的余数。 如果参数为300 余数则为44,它就成了最后的状态退出码。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读