Linux shell 学习笔记(7)— 构建基本脚本(变量、重定向、管道、状态码)

1. 使用多个命令

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

$ date ; who
Mon Feb 21 15:36:09 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)
$

使用这种办法就能将任意多个命令串连在一起使用了,只要不超过最大命令行字符数 255 就行。

2. 创建 shell 脚本文件

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

#!/bin/bash

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

shell 会通过 PATH 环境变量来查找命令。

$ echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin
:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/user/bin 
$

PATH 环境变量被设置成只在一组目录中查找命令。要让 shell 找到 test1 脚本,只需采取以下两种作法之一:

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

3. 显示消息

在 echo 命令后面加上了一个字符串,该命令就能显示出这个文本字符串

$ echo This is a test
This is a test
$

默认情况下,不需要使用引号将要显示的文本字符串划定出来。

echo 命令可用单引号或双引号来划定文本字符串。如果在字符串中用到了它们,你需要在文本中使用其中一种引号,而用另外一种来将字符串划定起来。

$ 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 参数

echo -n "The time and date are: $(date)"

4. 使用变量

4.1 环境变量

shell 维护着一组环境变量,用来记录特定的系统信息。比如系统的名称、登录到系统上的用户名、用户的系统 ID(也称为UID)、用户的默认主目录以及 shell 查找程序的搜索路径。可以用 set 命令来显示一份完整的当前环境变量列表。

$ set
BASH=/bin/bash
[...]
HOME=/home/Samantha
HOSTNAME=localhost.localdomain
HOSTTYPE=i386
IFS=$' \t\n'
IMSETTINGS_INTEGRATE_DESKTOP=yes
IMSETTINGS_MODULE=none
LANG=en_US.utf8
LESSOPEN='|/usr/bin/lesspipe.sh %s'
LINES=24
LOGNAME=Samantha
[...]

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

$ cat test2
#!/bin/bash
# display user information from the system.
echo "User info for userid: $USER"
echo UID: $UID
echo HOME: $HOME
$
# 执行结果如下
$ ./test2
User info for userid: Samantha
UID: 1001
HOME: /home/Samantha
$

注意,echo 命令中的环境变量会在脚本运行时替换成当前值。另外,在第一个字符串中可以将 $USER 系统变量放置到双引号中,而 shell 依然能够知道我们的意图。

要显示美元符,你必须在它前面放置一个反斜线。

$ echo "The cost of the item is \$15"
The cost of the item is $15

4.2 用户变量

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

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

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

$ cat 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"
$

运行脚本会有如下输出:

$ chmod u+x test3
$ ./test3
Katie checked in 10 days ago
Jessica checked in 5 days ago
$

变量每次被引用时,都会输出当前赋给它的值。重要的是要记住,引用一个变量值时需要使用美元符,而引用变量来对其进行赋值时则不要使用美元符。

4.3 命令替换

命令替换允许你将 shell 命令的输出赋给变量。有两种方法反引号字符(`)、$() 格式。

  • 要么用一对反引号把整个命令行命令围起来:
  • 要么使用$()格式:
testing='date'
testing=$(date)

shell 会运行命令替换符号中的命令,并将其输出赋给变量 testing。注意,赋值等号和命令替换字符之间没有空格。

警告 命令替换会创建一个子 shell 来运行对应的命令。子 shell(subshell)是由运行该脚本的 shell所创建出来的一个独立的子shell(child shell)。正因如此,由该子 shell 所执行命令是无法使用脚本中所创建的变量的。在命令行提示符下使用路径./运行命令的话,也会创建出子 shell;要是运行命令的时候不加入路径,就不会创建子 shell。如果你使用的是内建的 shell 命令,并不会涉及子 shell。在命令行提示符下运行脚本时一定要留心!

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
$

要将命令的输出追加到已有文件中,可以用双大于号(>>)来追加数据。

5.2 输入重定向

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

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

command < inputfile

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

$ wc < test6
2 11 60
$

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

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

command << marker
data
marker

6. 管道

管道被放在命令之间,将一个命令的输出重定向到另一个命令中:

command1 | command2

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

7. 执行数学运算

7.1 expr 命令

expr 命令允许在命令行上处理数学表达式,但是特别笨拙。expr 命令能够识别少数的数学和字符串操作符,一般不推荐使用。

$ expr 1 + 5
6
$ expr 5 * 2
expr: syntax error
$
# 需要使用转义字符反斜线将*号标识出来
$ expr 5 \* 2
10
$

7.2 使用方括号

在将一个数学运算结果赋给某个变量时,可以用美元符和方括号($[ operation ])将数学表达式围起来。该方法比较常用,但仅支持整数运算。

$ var1=$[1 + 5]
$ echo $var1
6
$ var2=$[$var1 * 2]
$ echo $var2
12
$

7.3 浮点解决方案

使用 bc工具

8. 退出脚本

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

8.1 查看退出状态码

Linux 提供了一个专门的变量 $? 来保存上个已执行命令的退出状态码。对于需要进行检查的
命令,必须在其运行完毕后立刻查看或使用 $? 变量。它的值会变成由 shell 所执行的最后一条命令的退出状态码。

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

一个成功结束的命令的退出状态码是 0。

状态码描述
0命令成功结束
1一般性未知错误
2不适合的shell命令
126命令不可执行
127没找到命令
128无效的退出参数
128+x与Linux信号x相关的严重错误
130通过Ctrl+C终止的命令
255正常范围之外的退出状态码

8.2 exit 命令

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

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

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

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

$ chmod u+x test13
$ ./test13
The answer is 40
$ echo $?
5
$

退出状态码最大只能是 255。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wohu007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值