Shell编程—构建基本脚本

1. 使用多个命令

如果要两个命令或者多个命令一起运行,可以把它们放在同一行中,彼此间用分号隔开。

2. 创建 shell 脚本文件

在创建shell脚本文件时,必须在文件的第一行指定要使用的shell。其格式为:

#!/bin/bash

在通常的shell脚本中,井号(#)用作注释行。shell并不会处理shell脚本中的注释行。然而,shell脚本文件的第一行是个例外,#后面的惊叹号会告诉shell用哪个shell来运行脚本(是的,你可以使用bash shell,同时还可以使用另一个shell来运行你的脚本)。

在指定了shell之后,就可以在文件的每一行中输入命令,然后加一个回车符。之前提到过,注释可用#添加。例如:

#!/bin/bash # This script displays the date and who‘s logged on
date
who

这就是脚本的所有内容了。可以根据需要,使用分号将两个命令放在一行上,但在shell脚本中,你可以在独立的行中书写命令。shell会按根据命令在文件中出现的顺序进行处理。

还有,要注意另有一行也以#开头,并添加了一个注释。shell不会解释以#开头的行(除了以 #!开头的第一行)。留下注释来说明脚本做了什么,这种方法非常好。

将这个脚本保存在名为test1的文件中,基本就好了。在运行新脚本前,还要做其他一些事。

现在运行脚本,结果可能会叫你有点失望:

$ test1 bash: test1: command not found

bash shell找不到你的脚本文件,要让shell找到test1脚本,只需采取以下两种作法之一:

  1. 将shell脚本文件所处的目录添加到PATH环境变量中;
  2. 在提示符中用绝对或相对文件路径来引用shell脚本文件。

在这个例子中,我们用第二种方式将脚本文件的确切位置告诉shell。记住,为了引用当前目录下的文件,可以在shell中使用单点操作符。

$ ./test1
bash: ./test1: Permission denied

现在找到了文件,但是shell指明了你还没有执行文件的权限。快速查看一下文件权限就能找到问题所在。

$ ls -l test1 -rw-rw-r--    1 user     user           73 Sep 24 19:56 test1

我们通过chmod命令赋予文件属主执行文件的权限。

$ chmod u+x test1
$ ./test1
Mon Feb 21 15:38:19 EST 2014
Christine tty2         2014-02-21 15:26
Samantha tty3         2014-02-21 15:26
Timothy  tty1         2014-02-21 15:26
user     tty7         2014-02-19 14:03 (:0)
user     pts/0        2014-02-21 15:21 (:0.0) 

3 显示消息

可以将echo语句添加到shell脚本中任何需要显示额外信息的地方。

$ vim test1 #!/bin/bash # This script displays the date and who‘s logged on echo  The time and date are:   date echo "Let‘s see who‘s logged into the system:" who

当运行这个脚本时,它会产生如下输出:

4. 使用变量

4.1环境变量

我们可以通过set命令查看系统的环境变量:

在脚本中,你可以在环境变量名称之前加上美元符($)来使用这些环境变量。下面的脚本

演示了这种用法:

$ vim test3
#!/bin/bash
# testing variables
days=10
guest="Katie"
echo "$guest checked in $days days ago"
days=5
guest="Jessica"
echo "$guest checked in $days days ago"

输出:

当shell脚本中遇到一些具有具体含义的字符时,不如$,我们可以通\来转义。

举例:

在这个例子中,脚本会尝试显示变量$1(但并未定义),再显示数字5,真正的做法:

4.2用户变量

用户变量可以是任何由字母、数字或下划线组成的文本字符串,长度不超过20个。用户变量区分大小写,所以变量Var1和变量var1是不同的。使用等号将值赋给用户变量,在变量、等号和值之间不能出现空格。

$ vim test3
#!/bin/bash
# testing variables
days=10
guest="Katie"
echo "$guest checked in $days days ago"
days=5
guest="Jessica"
echo "$guest checked in $days days ago"

输出:

要调用一个变量时,要用$符号:

$ vim test4
#!/bin/bash
# assigning a variable value to another variable
 value1=10
 value2=$value1
 echo "The resulting value is $value2"

输出:

要是忘了用美元符,使得value2的赋值行变成了这样:

value2=value1

那你会得到如下输出:

4.3命令替换

shell脚本中,有用的特性之一就是可以从命令输出中提取信息,并将其赋给变量。把输出赋给变量之后,就可以随意在脚本中使用了。

有两种方法可以将命令输出赋给变量:

  1. 反引号字符(`)
  2. $()格式

要注意反引号字符,在美式键盘上,它通常和波浪线(~)位于同一键位。

使用普通的shell命令输出创建变量的例子:

$ vim test5
#!/bin/bash
testing=$(date)
echo "The date and time are: " $testing

变量testing获得了date命令的输出,然后使用echo语句显示出它的值。运行这个shell脚本生成如下输出:

再举一个例子:通过命令替换获得当前日期并用它来生成唯一文件名。

#!/bin/bash
# copy the /usr/bin directory listing to a log file
today=$(date +%y%m%d)
ls /usr/bin -al > log.$today 

运行该脚本之后,应该能在目录中看到一个新文件:

-rw-r--r--    1 user     user          769 Jan 31 10:15 log.191125

5重定向输入和输出

重定向可以用于输入,也可以用于输出,可以将文件重定向到命令输入.

5.1输出重定向

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

command > outputfile

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

$ date > test6
$ ls -l test6
-rw-r--r--    1 user     user           29 Feb 10 17:56 test6
$ cat test6
Thu Feb 10 17:56:58 EDT 2014

重定向操作符创建了一个文件test6(通过默认的umask设置),并将date命令的输出重定向到该文件中。如果输出文件已经存在了,重定向操作符会用新的文件数据覆盖已有文件。

$ who > test6
$ cat test6
user     pts/0    Feb 10 17:55

现在test6文件的内容就是who命令的输出。

你可能并不想覆盖文件原有内容,而是想要将命令的输出追加到已有文件中,比如你正在创建一个记录系统上某个操作的日志文件。在这种情况下,可以用双大于号(>>)来追加数据:

$ date >> test6
$ cat test6
user     pts/0    Feb 10 17:55 Thu Feb 10 18:02:14 EDT 2014

5.2输入重定向

输入重定向和输出重定向正好相反。输入重定向将文件的内容重定向到命令,而非将命令的输出重定向到文件。输入重定向符号是小于号(<):

command < inputfile

一个简单的记忆方法就是:在命令行上,命令总是在左侧,而重定向符号“指向”数据流动的方向。小于号说明数据正在从输入文件流向命令。

$ wc < test6
 2      11      60

wc命令可以对对数据中的文本进行计数。默认情况下,它会输出3个值:

  1. 文本的行数
  2. 文本的词数
  3. 文本的字节数

内联输入重定向符号是远小于号(<<)。除了这个符号,你必须指定一个文本标记来划分输入数据的开始和结尾。任何字符串都可作为文本标记,但在数据的开始和结尾文本标记必须一致。

command << marker data marker

下面是它的使用情况:

$ wc << EOF
> test string 1
> test string 2
> test string 3
> EOF
3       9      42

6管道

我们用不着将命令输出重定向到文件中,可以将其直接重定向到另一个命令,这个过程叫作管道连接。符号是(|),在美式键盘上,它通常和反斜线(\)位于同一个键。管道被放在命令之间,将一个命令的输出重定向到另一个命令中:

command1 | command2

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

也可以用一条文本分页命令(例如less或 more)来强行将输出按屏显示。

$ rpm -qa | sort | more

7执行数学运算

7.1expr命令

expr命令能够识别少数的数学和字符串操作符:


操 作 符


描  述


ARG1 | ARG2


如果ARG1既不是null也不是零值,返回ARG1;否则返回ARG2


ARG1 & ARG2


如果没有参数是null或零值,返回ARG1;否则返回0


ARG1 < ARG2


如果ARG1小于ARG2,返回1;否则返回0


ARG1 <= ARG2


如果ARG1小于或等于ARG2,返回1;否则返回0


ARG1 = ARG2


如果ARG1等于ARG2,返回1;否则返回0


ARG1 != ARG2


如果ARG1不等于ARG2,返回1;否则返回0


ARG1 >= ARG2


如果ARG1大于或等于ARG2,返回1;否则返回0


ARG1 > ARG2


如果ARG1大于ARG2,返回1;否则返回0


ARG1 + ARG2


返回ARG1和ARG2的算术运算和


ARG1 - ARG2


返回ARG1和ARG2的算术运算差


ARG1 * ARG2


返回ARG1和ARG2的算术乘积


ARG1 / ARG2


返回ARG1被ARG2除的算术商


ARG1 % ARG2


返回ARG1被ARG2除的算术余数


STRING : REGEXP


如果REGEXP匹配到了STRING中的某个模式,返回该模式匹配


match STRING REGEXP


如果REGEXP匹配到了STRING中的某个模式,返回该模式匹配


substr STRING POS LENGTH


返回起始位置为POS(从1开始计数)、长度为LENGTH个字符的子字符串


index STRING CHARS


返回在STRING中找到CHARS字符串的位置;否则,返回0


length STRING


返回字符串STRING的数值长度


+ TOKEN


将TOKEN解释成字符串,即使是个关键字


(EXPRESSION)


返回EXPRESSION的值

$ vim test6
#!/bin/bash
# An example of using the expr command
var1=10
var2=20
var3=$(expr $var2 / $var1)
echo The result is $var3

输出:

7.2使用方括号

$ vim test7
#!/bin/bash
var1=100
var2=50
var3=45
var4=$[$var1 * ($var2 - $var3)]
echo The final result is $var4

输出:

在bash shell脚本中进行算术运算会有一个主要的限制。请看下例:

$ vim test8
#!/bin/bash
var1=100
var2=45
var3=$[$var1 / $var2]
echo The final result is $var3 

输出:

bash shell数学运算符只支持整数运算。若要进行任何实际的数学计算,这是一个巨大的限制。

7.3 浮点解决方案

1. bc的基本用法

bash计算器实际上是一种编程语言,它允许在命令行中输入浮点表达式,然后解释并计算该表达式后返回结果。bash计算器能够识别:

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

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

浮点运算是由内建变量scale控制的。必须将这个值设置为你希望在计算结果中保留的小数位数,否则无法得到期望的结果:

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

变量一旦被定义,你就可以在整个bash计算器会话中使用该变量了。print语句允许你打印变量和数字。

2. 在脚本中使用bc

基本格式如下:

variable=$(echo "options; expression" | bc)

第一部分options允许你设置变量。如果你需要不止一个变量,可以用分号将其分开。expression参数定义了通过bc执行的数学表达式。这里有个在脚本中这么做的例子:

$ vim test10
#!/bin/bash
var1=100
var2=45
var3=$(echo "scale=4; $var1 / $var2" | bc)
echo The answer for this is $var3

输出:

此外,还可以这样来处理数据较大的:

$ cat test12
#!/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 + b1
EOF
)

echo $var5

输出:

2813.9882

8退出脚本

shell中运行的每个命令都使用退出状态码(exit status)告诉shell它已经运行完毕。退出状态码是一个0~255的整数值,在命令结束运行时由命令传给shell。


状 态 码


描  述


0


命令成功结束


1


一般性未知错误


2


不适合的shell命令


126


命令不可执行


127


没找到命令


128


无效的退出参数


128+x


与Linux信号x相关的严重错误


130


通过Ctrl+C终止的命令


255


正常范围之外的退出状态码

查看状态码:

$ date
Sat Jan 15 10:01:30 EDT 2014
$ echo $?
0

exit命令允许你在脚本结束时指定一个退出状态码:

$ cat test13
#!/bin/bash
# testing the exit status
var1=10
var2=30
var3=$[$var1 + $var2]
echo The answer is $var3
exit 5

当查看脚本的退出码时,你会得到作为参数传给exit命令的值:

特别注意,退出状态码被缩减到了0~255的区间。shell通过模运算得到这个结果。所以最终的结果是指定的数值除以256后得到的余数。比如指定的状态码值是300,那么最终的状态退出码是44(300%256=44)。

原文地址:https://www.cnblogs.com/ericz2j/p/12045503.html

时间: 2024-10-10 14:52:32

Shell编程—构建基本脚本的相关文章

shell编程之服务脚本编写,文件锁以及信号捕获

shell脚本编程是linux运维工程师必备的技能,也是非常重要的一个技能,所以把shell编程学好,只有好处.基础语法我也就不讲了,学过C语言这些语言的,稍微看一下就能明白shell编程的基础,所以我们直接切入正题. 开班第20天: 今天的课程大纲: shell编程中的函数 编写一个自动挂载的脚本 利用autofs怎么实现自动挂载 文件锁和信号捕获trap sed流文件编辑器 详细讲解: shell编程中的函数 shell中,我们定义函数的方法有两种: 下面调用的时候,直接调用函数名就可以了

linux基础之shell编程(3)-给脚本设置参数

bash的变量类型 本地变量(局部变量) 环境变量 位置变量:$1,$2,$3, ... 特殊变量:$?,$#,$*,[email protected] 那让脚本拥有获取外界参数的能力就要用的位置变量,$1代表第一个参数,$2代表第二个参数,依次类推 例: vartest.sh #!/bin/bash # ONEVAR=$1 TWOVAR=$2 THREEVAR=$3 echo "第一个参数是:${ONEVAR}" echo "第二个参数是:${TWOVAR}" e

Shell编程(脚本)的常用命令和语句

一些常用的Shell编程(脚本)命令和语句,可以满足一般需求. 接收到的命令参数: 参数个数: $# 参数值: 命令本身:$0 第一个参数:$1 第二个参数:$2 -- 退出命令: exit echo命令: 换行: echo 输出后不换行: echo -n "请选择(y/n)?" 利用转义符号输出双引号: echo "欢迎使用\"正式服务器\"部署工具." 输出中带变量: echo "即将部署项目:$project_name"

shell编程脚本语法

学习了两个月的Linux,记住了很多命令,知道了脚本的作用,也被脚本杀死了大概一半的脑细胞,现在脚本还不能熟练运用,感觉亏了.心疼我的脑细胞,痛恨脚本,但不得不说,脚本是一个好东西啊,用起来真的方便,但是写起来真的烧脑袋呦!下面来总结一下这周学习的脚本语法,哇,语法虽然不多也不难,但是结合起来熟练运用还有一定的难度,何况现在的脚本才几行,以后要写几行,心里没点数吗!废话少说,开始 跳过最基础的命令行堆积的脚本,总结一下让脚本更简洁实用的语法 首先,条件选择if语句登场 if语句用法:常见的单分支

centos shell编程6一些工作中实践脚本 第四十节课

centos   shell编程6一些工作中实践脚本    第四十节课 上半节课 下半节课 f

centos shell编程5LANMP一键安装脚本 第三十九节课

centos shell编程5LANMP一键安装脚本  第三十九节课 上半节课 下半节课 f

《跟老男孩学Linux运维之shell编程实战》-第五章 shell脚本的条件测试

本文的知识点是关于shell脚本的条件测试的相关内容. 通常在shell脚本中我们需要做各式各样的条件判断,比如,测试一个文件是否存在.是否为文件或目录.是否 具有执行权限等等,所以在shell脚本中,条件判断还是至关重要的.接下来我们进入正题:shell脚本的条件测试. 1.在bash编程中,条件测试常用的语法形式如下表: 提示: 语法1中的test命令和语法2中的[]是等价的.语法3中的[[]]双中括号为扩展的test命令. 语法4中的(())常用于计算. 在双中括号[[]]中可以使用通配符

Shell编程(脚本)的经常使用命令和语句

一些经常使用的Shell编程(脚本)命令和语句,能够满足一般需求. 接收到的命令參数: 參数个数: $# 參数值: 命令本身:$0 第一个參数:$1 第二个參数:$2 -- 退出命令: exit echo命令: 换行: echo 输出后不换行: echo -n "请选择(y/n)?" 输出后不换行,并把光标移到最左(以便下次输出覆盖当前行) echo -ne "$i\r" 利用转义符号输出双引號: echo "欢迎使用\"正式server\&qu

shell编程(二)---shell脚本说明

脚本:命令的堆砌,根据实际情况,结合命令流程控制机制实现的源程序. 脚本的内容说明: 1. 以shebang开始,即#!/bin/bash.这里指定的是脚本解释器的路径. 2. 以#开始的表示注释,用于说明脚本的功能和作用. 3. 脚本的执行:可以直接给脚本赋予x权限,通过使用脚本所在的路径执行脚本,或者是脚本所在的目录添加到PATH变量中. 4. 如果通过sh的方式执行脚本时,脚本可以不需要具有x权限,并且脚本里面的第一行也可以不要写shebang. 示例1: [[email protecte