最近突然不忙了,想系统的学习一下shell编程。可以说对linux的熟悉离不开对shell的学习,而作为一个好的系统管理员,不能不懂shell编程。
shell编程不只是简单的命令堆叠,它还提供了变量,控制结构(if/for/while);可以说它和python、perl、ruby等3大脚步语言一样,但在一些本地的管理以及文件操作上,能提供更多的灵活性。
本学习笔记主要记录自己学习shell的过程,学习资料为《Shell 脚本学习指南》。
最简单的脚本只需要一个命令,直接从终端输入的一个命令可看出是最简单的一个脚本,如:ls,who等,ls列举对应目录下的各文件,who列举系统有哪些人在登陆。
管道符‘|’可以在两个命令之间建立管道(pipeline):一个命令的输出,成为另一命令的输入。如列举某文件夹下文件夹加文件的个数:
ls / |wc -l
'ls /'命令的结果作为‘wc -l’的输入,wc(字数计算程序)可以计算行(line)、字数(word)、字符数(character),-l选项计算行数,从而计算出文件夹或文件的个数。
通常一个脚本不止一两个命令,它是一些命令的组合加一些控制结构等等,一般我们会将其写入一个文本文件里面,然后用chmod +x 赋予其可执行的权限,默认情况下会调用/bin/sh(标准的shell)副本来执行该程序。现在,一般的linux系统都不止一个解释器,bash/csh/等。指定使用csh解释器,可再其第一行加入:
#! /bin/csh -f
通常使用绝对路径,避免找不到shell,下面则指定awk 解释器:
#! /bin/awk -f
Shell最基本的工作是执行一些系统命令,命令与参数的关系:命令+空白(space键或tab键)+参数。如:
ls -l cd /home
选项参数并不是必须的:ls命令不加‘-l'也可以运行,选项参数有两种格式’-‘或’--‘
如ls -a等效于ls --all
可以使用分号(;)分隔同一行的多条命令:cd /home;mkdir emptydir
使用& 将命令放入后台运行:gedit ~/.bashrc & 。这意味着shell不用等到该命令完成,就可以继续执行下一个命令。
shell识别3种基本的命令:内建命令、shell函数、外部命令:
a.建立新的进程,即shell副本。
b.新进程在PATH变量内列出目录中,寻找特定命令。如果命令名称中有’/‘符号,则略过路径查找。
c.新进程中,以找到的新程序取代shell程序并执行。
d.程序完成,最初的shell从终端或脚本里执行下一条命令。如下图所示:
脚本语言的变量使用都非常方便,下面是一个变量的应用:
myvar=this_is_a_var echo $myvar yourvar="this is your var" echo $yourvar
当变量赋值有空格时需要用“”将其括起来,使用$符号进行变量的引用。
echo:简单的文本输出使用echo即可,很方便,上面已经演示过它的使用了。复杂一点的打印可以用printf,它实现了C中printf函数类似的功能,如:
<:输入重定向
>:输出重定向,如果文件不存在,将新建一个,如果已经存在,将其覆盖
>>:附加到文件,如果文件不存在,将新建一个,如果已经存在,附加到文件尾部
下面的命令使用重定向备份bashrc文件:
$PATH变量指明到哪些路径下去查找相关命令,如将本目录加入可执行路径:
PATH=$PATH:.
'.'表示本目录,'..'表示上一目录。若要让上述设置永久有效,可将上述设置加入~/.bashrc文件尾。
#! /bin/sh echo the shell script is $0 ehco $1 this is your $2
将上述代码保持到文本文件myecho,用chmod +x myecho赋予其可执行权限,执行上述命令上述命令输出为:
shell命令和参数直接用空白隔开,并且会依次存入$0、$1、$2等shell自动变量中,在脚本中可用$0/$1等访问相关参数。
方式1:sh -x 脚本;被跟踪的脚本前会有一个+号,此时脚本内所有命令将被跟踪,能快速定位出错的程序段,其结果如下:
方式2:在脚本中使用set -x和set +x来打开跟踪和关闭跟踪,这通常在大的脚本中跟踪某一段程序。将上述代码改为:
#! /bin/sh set -x echo the shell script is $0 set +x echo $1 this is your $2
结果为:
set +x命令也被跟踪到,因为跟踪是在它执行完后才关闭,set -x不被跟踪,set -x执行完后才会打开跟踪。