Shell Script

目录

创建脚本

显示消息

变量

创建变量

只读变量

删除变量

命令替换

重定向输入和输出

输出重定向

输入重定向

管道

数学运算

方括号

浮点解决方案

退出脚本


创建脚本

在创建shell脚本文件时,必须在文件的第一行指定要使用的shell。通常井号(#)用作注释行,但第一行是个例外

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

脚本保存在名为test1的文件中,在直接运行脚本时会出现下面问题:

$ test1
bash: test1: command not found

你要跨过的第一个障碍是让bash shell能找到你的脚本文件,只需采取以下三种作法之一:

  • 将shell脚本文件所处的目录添加到PATH环境变量中;
$ PATH=$PATH:.
$ test1
  • 作为解释器参数:直接运行解释器,其参数就是 shell 脚本的文件名
/bin/bash test.sh

这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

  • 在提示符中用绝对或相对文件路径来引用shell脚本文件(需要修改权限)

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

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

现在shell找到了脚本文件,但还有一个问题。shell指明了你还没有执行文件的权限。下一步是通过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) $

显示消息

echo命令后面加上了一个字符串,该命令就能显示出这个文本字符串。echo命令可用单引号或双引号来划定文本字符串

$ echo This is a test
This is a test
$ echo Let's see if this'll work
Lets see if thisll work
$ echo "This is a test to see if you're paying attention"
This is a test to see if you're paying attention
$ echo 'Rich says "scripting is easy".'
Rich says "scripting is easy".

在脚本运行中,但如果想把文本字符串和命令输出显示在同一行中,可以用echo语句的-n参数。

#!/bin/bash
echo -n "The time and date are: "

date

$ ./test1
The time and date are: Mon Feb 21 15:42:23 EST 2014

变量

  • 创建变量

除了环境变量,shell脚本还允许在脚本中定义和使用自己的变量。使用等号将值赋给用户变量。在变量、等号和值之间不能出现空格。shell脚本会自动决定变量值的数据类型

var1=10
var2=-57
var3=testing
var4="still more testing"

使用一个定义过的变量,只要在变量名前面加美元符号即可

  • 只读变量

readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变,也不能被删

$ readonly var1=10
$ var=11
-bash: var: 只读变量
  • 删除变量

$ unset var
-bash: unset: var: 无法反设定: 只读 variable
$ unset var1
$ echo $var1
$
  • 命令替换

  从命令输出中提取信息,并将其赋给变量,$()格式命令输出赋给变量。shell会运行命令替换符号中的命令,并将其输出赋给变量testing

$ testing=$(date)

下面例子中,在脚本中通过命令替换获得当前日期并用它来生成唯一文件名 。today变量是被赋予格式化后的date命令的输出。+%y%m%d格式告诉date命令将日期显示为两位数的年月日的组合。

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

  

$ date +%y%m%d
140131
$

重定向输入和输出

  • 输出重定向

最基本的重定向将命令的输出发送到一个文件中。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
$

双大于号(>>)命令将输出追加到已有文件中

  • 输入重定向

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

command < inputfile

wc命令可以对对数据中的文本进行计数。默认情况下,它会输出3个值: 文本的行数; 文本的词数; 文本的字节数。
通过将文本文件重定向到wc命令,你立刻就可以得到文件中的行、词和字节的计数

$ wc < test6
2 11 60
$

还有另外一种输入重定向的方法,称为内联输入重定向。这种方法无需使用文件进行重定向,只需要在命令行中指定用于输入重定向的数据就可以了。 

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

command << marker    #marker为文本标记符
data                #data为输入给command的数据
marker

在命令行上使用内联输入重定向时,shell会用PS2环境变量中定义的次提示符来提示输入数据。

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

 

管道

有时需要将一个命令的输出作为另一个命令的输入。这可以用重定向来实现,只是有些笨拙。通过标准输出重定向,rpm命令的输出被重定向到了文件 rpm.list。命令完成后,rpm.list保存着系统中所有已安装的软件包列表。接下来,输入重定向将rpm.list文件的内容发送给sort命令,该命令按字母顺序对软件包名称进行排序。

$ rpm -qa > rpm.list
$ sort < rpm.list
abrt-1.1.14-1.fc14.i686
abrt-addon-ccpp-1.1.14-1.fc14.i686
abrt-addon-kerneloops-1.1.14-1.fc14.i686
abrt-addon-python-1.1.14-1.fc14.i686
acl-2.2.49-8.fc14.i686
[...]

我们用不着将命令输出重定向到文件中,可以将其直接重定向到另一个命令。这个过程叫作管道连接。在第一个命令产生输出的同时,输出会被立即送给第二个命令。数据传输不会用到任何中间文件或缓冲区。

command1 | command2
$ rpm -qa | sort
abrt-1.1.14-1.fc14.i686
abrt-addon-ccpp-1.1.14-1.fc14.i686
abrt-addon-kerneloops-1.1.14-1.fc14.i686
abrt-addon-python-1.1.14-1.fc14.i686
acl-2.2.49-8.fc14.i686
[...]

可以在一条命令中使用任意多条管道 

$ rpm -qa | sort | more

可以搭配使用重定向和管道来将输出保存到文件中

$ rpm -qa | sort > rpm.list

数学运算

  • 方括号

 在bash中,在将一个数学运算结果赋给某个变量时,可以用美元符和方括号($[ operation ])将数学表达式围起来。bash shell数学运算符只支持整数运算

$ var1=$[1 + 5]
$ echo $var1
6
$ var2=$[$var1 * 2]
$ echo $var2
12
$
  • 浮点解决方案

 内建的bash计算器,叫作bc。要退出bash计算器,你必须输入quit

$ 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*0.5
6.0
quit
$

浮点运算是由内建变量scale控制的。scale变量的默认值是0。在scale值被设置前,bash计算器的计算结果不包含小数位。在将其值设置成4后,bash计算器显示的结果包含四位小数。-q命令行选项可以不显示bash计算器冗长的欢迎信息。

$ bc -q
3.44 / 5
0
scale=4
3.44 / 5
.6880
quit
$

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

$ bc -q
var1=10
var1 * 4
40
quit
$

在脚本中使用bc

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

第一部分options允许你设置变量。如果你需要不止一个变量,可以用分号将其分开。expression参数定义了通过bc执行的数学表达式。

$ cat test9
#!/bin/bash
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The answer is $var1
$ chmod u+x test9
$ ./test9
The answer is .6880

退出脚本

shell中运行的每个命令都使用退出状态码(exit status)告诉shell它已经运行完毕。退出状态码是一个0~255的整数值,在命令结束运行时由命令传给shell。可以捕获这个值并在脚本中使用。Linux提供了一个专门的变量$?来保存上个已执行命令的退出状态码。

Linux退出状态码
0命令成功结束$ date
Sat Jan 15 10:01:30 EDT 2014
$ echo $?
0
1一般性未知错误(是给某个命令提供了无效参数)$ date %t
date: invalid date '%t'
$ echo $?
1
$
2不适合的shell命令 
126命令不可执行(没有权限)$ ./myprog.c
-bash: ./myprog.c: Permission denied
$ echo $?
126
$
127没找到命令$ asdfg
-bash: asdfg: command not found
$ echo $?
127
128无效的退出参数 
130通过Ctrl+C终止的命令 
255正常范围之外的退出状态码 

默认情况下,shell脚本会以脚本中的最后一个命令的退出状态码退出。exit命令允许你在脚本结束时指定一个退出状态码。可以在exit命令的参数中使用变量.

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值