从今天開始,我们一起来学习《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,都会看到类似user@hostname:/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