从今天开始,我们一起来学习《linux shell脚本攻略》这本书。
1.1简介
shell脚本通常是一个以#!起始的文本文件,如下所示:
#!/bin/bash
有两种执行shell脚本的方式,分别如下:
sh script.sh 或者./script.sh
但是在执行脚本以前,我们需要给脚本执行权限才行,不然脚本无法执行
chmod a+x script.sh
在命令中行中,如果需要同时执行多个命令,可以使用
cmd1;cmd2
1.2中断打印
1.2.1 实战演练
echo 是用于中断打印的基本命令。
在默认情况下,echo在每次调用后会添加一个换行符。
只需要使用带双引号的文本,结合echo命令就可以将该文本在中断上打印出来,类似的,不待双引号的文本也可以得到童谣的输出结果:
使用单引号看起来也可以完成同样的任务:
这些方法看起来相思,但各有一些特殊用途和副作用,看看下面这行命令:
看到命令行抛出一个错误,说不能带有感叹号。因此,如果希望打印感叹号,那就不要将其放入双引号中,或者你可以在其之前加上一个特殊的转移字符斜杠将感叹号转移:
在使用带单引号的echo时,Bash不会对单引号中的变量(如$var)求值,而只是照原样显示
另一个可以打印的命令是printf,printf使用的参数和c语言中的printf函数一样。如:
看到没,printf打印出来的输出是没有带换行的。
1.2.2补充内容:
打印彩色输出。每种颜色都有对应的颜色码,比如:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37.要打印彩色文本,可以输入如下命令:
1.3 玩转变量和环境变量
1.3.1 实战演练
一个变量可以通过以下方式进行赋值:
var=value
var是变量名,value是赋给变量的值,如果value不包含任何空白字符,那么它不需要使用引号进行引用,繁殖,则必须使用单引号或双引号。注意,var = value不同于var=value.把var=value改写成var = value使用常见错误,但前者是赋值操作,后者则是相等操作。在变量名之前加上$前缀就可以打印出变量的内容
var="value"
echo $var 或者echo ${var},可以看到下图中,第一个命令是错误的,第二三个命令整错打印出了变量内容:
我们也可以在printf或echo命令的双引号中引用变量值:
export命令用来设置环境变量。至此之后,从当前shell脚本执行的任何程序都会继承这个变量。我们可以按照自己的需要,在执行的应用程序或者shell脚本中导出特定变量。在默认情况下,有很多标准环境变量可供shell使用。PATH就是其中之一
$ echo $PATH
通常$PATH的值在/etc/environment或者/etc/profile或者~/.bashrc中定义。如果需要在PATH中添加一条新路径,可以使用:
export PATH=$PATH:/home/user/bin
1.3.2 补充内容:
获取字符串的长度,可以使用下面的方法或者:
识别当前shell的版本:
echo $SHELL 或者echo $0
修改Bash提示字符串
当我们打开一个终端或是运行一个shell,都会看到类似[email protected]:/home/$的提示字符串。不同的GNU/Linux发布版本中的提示及颜色也略有不同。我们可以利用PS1环境变量来定制提示文本。默认的shell提示文本是在文件~/.bashrc中的某一行设置的。可以使用如下命令列出设置PS1的那一行:
如果要设置提示字符串,可以输入:
PS1=">",如下图所示,提示符已经变成">"尖括号了,但是这样的修改只对当前的这个终端起作用,如果再新开一个终端或者电脑重启,则会恢复到修改以前的提示符。要想设置之后生效,就必须修改~/.bashrc中的值才可以。
1.4 通过shell进行数学运算
1.4.1 预备知识
再Bash shell环境中,可以利用let,(())和[]执行基本的算术操作。而在进行高级操作时,expr和bc这两个工具也会非常有用。
1.4.2 实战演练
可以用普通的变量赋值方法定义数值,这时,它会被存储为字符串。然而,我们可以用一些方法使它能像数字一样进行处理,如下图所示:
当然还可以进行变量的自增或者自减操作:
其它的算术操作方式:
bc是一个用于数学运算的高级工具,这个精密计算器包含了大量的选项。我们可以借助它执行浮点数运算并应用一些高级函数:
对设置bc参数的其它操作:
1.5 玩转文件描述符和重定向
?1.5.1 预备知识
?我们在编写脚本的时候会频繁使用标准输入(stdin),标准输出(stdout)和标准错误(stderr)。通过内容过滤将输出重定向到文件是我们从事的基础任务之一。当命令输出文本的时候,这些输出文本有可能是错误信息,也有可能是正常的(非错误的)输出信息。单靠查看输出的文本本身,我们没法区分哪些是正常的输出文本,哪些是错误文本。不过,我们可以通过文件描述符来解决这个问题,将哪些与特定描述符关联的文本提取出来。
?文件描述符是与一个打开的文件或数据流相关联的整数。文件描述符0,1以及2是系统预留的。
? ?0-----------stdin(标准输入)
? ?1-----------stdout(标准输出)
? ?2-----------stderr(标准错误)
?1.5.2 实战演练
? ?用下面的方法可以将输出文本重定向或保存到一个文件中:
? ?echo "This is a sample text 1" > temp.txt
? ?这种方法通过截取文件方式,将输出文本存储到文件temp.txt中,也就是说在把echo命令的输出写入文件之前,temp.txt中的内容首先会被清空。
? ?接下来再看另一个例子:
? ?echo "This is a sample text 2" >> temp.txt
? ?这种方法将会将文本追加到目标文件中。
? ?>和>>并不相同。尽管这两个操作符都可以将文本重定向到文件,但是前者会先清空文件,再写入内容,而后者将内容追加到现有文件的尾部。
? ?
? ?来看看什么是标准错误以及如何对它重定向。当命令输出错误信息时,stderr信息就会被打印出来。看看下面的例子:
? ?
这里,+是一个非法参数,因此将返回错误信息。注意:当一个命令发生错误并退回时,它会返回一个非0的退出状态;而当命令成功完成后,它会返回数字0,退出状态可以从特殊变量$?中获得(在命令执行之后立刻运行echo
$?,就可以打印出退出状态)
? ?接下来,我们不让错误信息打印在终端,而是存入一个文件中:
? ?注意命令是ls + 2>out.txt。错误信息输出到out.txt中
? ?我们也可以将标准输出和标准错误信息一同来执行到同一个命令中:
? ?可以看到,错误信息和标准输出被输出到不同的文件当中了。还可以通过如下的命令将stderr转换成stdout,使得stderr和stdout都被重定向到同一个文件中:
? ?cmd 2>&1 output.txt 或者cmd &> output.txt。有时候,在输出中可能包含一些不必要的信息。如果你不想让终端中充斥着有关stderr的繁枝末节,那么你可以将stderr的输出重定向到/dev/null,保证一切都会被清除的干干净净。假设我们有三个文件,分别是a1,a2,a3。但是普通用户对文件a1没有“读-写-执行”权限。如果你需要打印文件名以a起始的所有文件的内容,你可以使用cat命令:
? ?可以看到,a1文件已经没有任何权限,但是因为我是用root用户登录,所以还是可以读内容的,如果其它用户读取a1,则会报错,这时我们就可以使用标准错误输出来捕获错误输出,然后输出其它文件的内容:
? ?
?1.5.3
补充内容? ? ?
? ?从stdin读取输入的命令能以多种方式接受数据。另外,还可以用cat和管道来制定我们自己的文件描述符,例如:
? ?cat file | cmd
? ?cmd1 | cmd2
? ?将文件重定向到命令:
? ?cmd < file
(linux shell)第一章--小试牛刀(上)