Shell脚本学习指南笔记

 
 

入门 
Shell脚本最常用于系统管理工作,或者用于结合现有的程序以完成小型、特定的工作。 
脚本编程语言与编译型语言的差异 
许多中、大型程序都是编译型语言,如Fortran、Ada、C、C++或者Java(有些特殊)。这类程序只要从源代码(Source Code)转换成目标代码(Object Code)便能直接通过计算机执行。这样的好处是高效,缺点是它们多半运行于底层,处理的是字节、数字或是机器层级的对象,很难进行“将一个目录里所有文件复制到另一个目录中”这类对文件的简单操作。 
脚本语言通常是解释型(interpreted)的,由解释器(interpreter)读入程序代码,将其转换成内部形式。好处是它们多半运行在比编译型语言高的层次,能够轻易处理文件与目录之类的对象,缺点是效率不如编译型。但是编写更快,而且目前的速度也已经足够快,常用脚本语言有:awk、Perl、Python、Ruby与Shell。Shell的特点有: 
1. 简单性 2. 可移植性 3. 开发容易 
一个简单的脚本 
who命令可以知道系统有谁登陆,如果有很多用户在登陆,结果会很长,可以使用wc(字数统计)命令,算出行数(line)、字数(word)和字符数(character)。可以使用wc –l,只计算出行数 
$ who | wc –l 
| 管道符号可以在两个命令之间建立管道(pipeline):who的输出成为了wc的输入。下面就写一个shell脚本将管道转变成一个独立的命令。 
 
其实在Shell中开发周期很类似,先直接在命令行上测试,之后写入到独立的脚本中。 
第一行的#! 
当Shell执行一个程序时,要求Unix内核启动一个新的进程(process),在该进程里执行指定的程序。内核知道怎样为编译型程序执行,但Shell是解释型程序,当Shell要求内核执行时,内核无法执行,会回应”not executable format file”不是可执行的格式文件的错误信息。Shell收到此错误信息时,就会确定不是编译型程序,是Shell脚本,接着会启动一个新的/bin/sh副本来执行该程序。 
在当前有很多种Shell,需要通过第一行#!来指定用哪个Shell来执行。一般如下: #!  解释器地址  选项 比如标准的Shell脚本: #! /bin/sh

 
 2 
或者独立的awk程序: 
#! /bin/awk –f      这样就表示为是一个awk程序。 下面有些陷阱(gotchas)需要注意: 
1. 系统对第一行#!长度是有限制的,从63到1024个字符不等,因此尽量不要超过64个字符 2. 别在选项之后放置任何空白,因为空白也会跟着选项一起传递给被引用程序 3. 知道解释器的完整路径,可以用来规避可一直行问题。 
  下面的写法可以避免某种程度的欺骗式攻击(Spoofing Attack)。即添加选项符-,但不添加选项内容 
#! /bin/sh - 
Shell元素 
命令与参数 
Shell最基本工作就是执行命令。以空白隔开命令行的各个部分。命令行可以有选项option,分号;可用来分割同一行里的多条命令。如果使用的是&符号而不是分号,则Shell将在后台执行其前面的命令,即Shell不用等到该命令完成,就可以继续执行下一个命令。 
变量 
Shell里变量值可以是(而且通常是)空值null,即不包含任何字符。变量名以字母或者下划线开头,后面接任意长度的字母、数字或下划线。定义如下: 
first = hello 
引用该变量值,前面加上$,如 echo $first 
如果值中含有空格时,需要加上引号。 second = Hello world  one 
当将几个变量连接起来时,需要使用引号: fullname = “$first $second” 
printf输出 
echo输出在不同Unix版本之间选项有很大不同。有了printf命令,它模仿C程序库的printf()。语法格式如下: 
printf    string   arguments 例子: 
printf   “The first program always prints „%s, %s!‟\n”  Hello   World 
I/O重定向 
标准输入(standard input)、标准输出(standard output)和标准错误输出(standard error)。默认情况下,许多Unix程序会读取标准输入、写入标准输出,并将错误信息传递给标准错误输出。这类程序叫做过滤器(filter)。 
默认的这三类都是终端,通过cat命令可知:

 [.........] $cat

hello

hello

howareyou

howareyou

what is your name

what is your name

输入cat后,没有指定任何参数,读取标准输入,写入标准输出,当输入hello后,cat返回。 
a) 以 < 改变标准输入: 
program < file可将program的标准输入修改为file:

[..........]$cat > num

1 2 3

hello

how are you

首先向num文件中输入数据,之后使用tr –d „r‟命令:

[..........]$ tr -d 'r' < num

1 2 3

hello

how are you

 
 tr用来从标准输入中通过替换或删除操作进行字符转换。tr主要用于删除文件中控制字符或进行字符转换。使用tr时要转换两个字符串:字符串1用于查询,字符串2用于处理各种转换。tr刚执行时,字符串1中的字符被映射到字符串2中的字符,然后转换操作开始。

带有最常用选项的tr命令格式为: 
    tr -c -d -s ["string1_to_translate_from"] ["string2_to_translate_to"] < input-file 
-c 用字符串1中字符集的补集替换此字符集,要求字符集为ASCII。 -d 删除字符串1中所有输入字符。 
-s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串。 input-file是转换文件名。虽然可以使用其他格式输入,但这种格式最常用。 因此上面输入重定向到文件num中,并删除字符r 
b) 以 > 改变标准输出: 
重定向符在目的文件不存在时,会创建一个,有的话就会覆盖。比如前面的 cat > file 
可以使用>>在目的文件后面添加内容。 
c) 以 | 建立管道 
| 前面命令的输出会作为第二个命令的输入。比如: tr  -d  „\r‟   <   dos-file.txt  |  sort  >  Unix-file.txt 
上面管道会先删除输入文件的回车符,在完成数据排序后,将结果输出到目的文件。 Tr用于转换字符 


特殊文件 
Unix有两个有用的特殊文件,第一个是/dev/null,是位桶(bit bucket)。传送到此文件的数据都会被系统丢掉。即当程序将数据写入到此文件时,实际上什么事都不会做。

[..........]$ cat num

1 2 3 

hello

how are you

[..........]$ cat num > /dev/null

[..........]$ cat /dev/null 


如果你需要的是命令的退出状态,而非它的输出,此功能会很有用。例如测试一个文件是否包含某个模式(pattern) 
if  grep  pattern  myfile  > /dev/null then 
    …    找到模式时 else 
    …    找不到模式时 fi  
另一个特殊文件时/dev/tty。当程序打开此文件时,Unix会自动将它重定向到一个终端再与程序结合。这在程序必须读取人工输入时(如密码)特别有用。此外,用它来产生错误信息也很方便,但很少有人这么用。


 
 
如果你需要的是命令的退出状态,而非它的输出,此功能会很有用。例如测试一个文件是否包含某个模式(pattern) 
if  grep  pattern  myfile  > /dev/null then 
    …    找到模式时 else 
    …    找不到模式时 fi  
另一个特殊文件时/dev/tty。当程序打开此文件时,Unix会自动将它重定向到一个终端再与程序结合。这在程序必须读取人工输入时(如密码)特别有用。此外,用它来产生错误信息也很方便,但很少有人这么用。 
 
stty(set tty)命令用来控制终端的各种设置,-echo用来关闭自动打印每个输入字符的功能。stty echo用来恢复该功能。 
基本命令查找 
Shell会沿着查找路径$PATH来寻找命令,这是以冒号分割的目录列表,可以在列表指定的目录下找到所要执行的命令。 
默认路径因系统而已,至少包含/bin与/usr/bin,如果要自己编写脚本,准备自己的bin目录来存放。步骤如下:


要让修改永久生效,在.profile文件中把你的bin目录假如$PATH,每次登录时Shell都将读取.profile文件。 
访问Shell脚本参数 
位置参数(position parameters)指的是Shell脚本的命令行参数。参数使用”$数字”的形式表示,当参数大于9时,使用${数字}。 
比如我们使用who | grep mushui命令来查找登录用户mushui的信息。写成Shell脚本为:


简单的执行跟着 
程序执行出错时,可以把执行跟踪(execution tracing)的功能打开。这会使Shell显示每个被执行到的命令,并在前面加”+”:一个加号后面跟着一个空格。 
可以在执行脚本时,使用 sh –x  脚本    
脚本的方式执行跟踪功能。 也可以在脚本中添加 set –x 
打开跟踪功能,使用set +x  关闭跟踪功能。 
查找与替换 
查找文本 
有三种程序可以用来查找整个文本文件:

 1. grep,使用基本的正则表达式

 2. egrep,使用扩展的正则表达式 
3. fgrep,快速grep,匹配固定字符串而不是正则表达式,并且grep与egrap只能匹配单个正则表
达式,而fgrep使用不同算法,能匹配多个字符串。 

grep –E 相当于egrep

 grep –F相当于是fgrep 
-i   列出匹配模式的文件名称,而不是打印匹配的行 
-q  如果模式匹配成功,则grep会成功离开,不讲匹配的行写入标准输出,否则即使不成功。

 -s  不显示错误信息,通常与-q并用

 -v  显示不匹配的行     

 
 
使用cut选定字段 
cut命令用来剪下文本文件里的数据,可以是字段类型或是字符类型。注意:一个制表符再次被视为单个字符。 
下面命令可显示系统上每个用户的登录名及其全名:


cut

语法如下:

 

cut 

 

-c 

 

 

list 

 

 

[file

cut 

 

-f 

 

 

list 

 

 

[ -d 

 

delim] 

 

[file

主要选项:

 

-c 

 

 

list 

 

 

 

 

 

以字符为主,执行剪下的操作。

list

为字符编号或一段范围的列表(以逗号分割)

1,3,5-12,42 

-d 

 

 

delim 

 

 

 

通过

-f

选项,使用

delim

作为定界符,上例中即使用“:

”作为定界符。默认为制表

符。

 

-f 

 

 

 

list 

 

 

 

 

 

以字段为主,作剪下的操作。

list

为字段编号或一段范围的列表。例子中即代表取

1

个和第

5

个。

cut

语法如下:

 

cut 

 

-c 

 

 

list 

 

 

[file

cut 

 

-f 

 

 

list 

 

 

[ -d 

 

delim] 

 

[file

主要选项:

 

-c 

 

 

list 

 

 

 

 

 

以字符为主,执行剪下的操作。

list

为字符编号或一段范围的列表(以逗号分割)

1,3,5-12,42 

-d 

 

 

delim 

 

 

 

通过

-f

选项,使用

delim

作为定界符,上例中即使用“:

”作为定界符。默认为制表

符。

 

-f 

 

 

 

list 

 

 

 

 

 

以字段为主,作剪下的操作。

list

为字段编号或一段范围的列表。例子中即代表取

1

个和第

5

个。

cut语法如下: 
cut  -c   list   [file…] 
cut  -f   list   [ -d  delim]  [file…] 主要选项: 
-c   list      以字符为主,执行剪下的操作。list为字符编号或一段范围的列表(以逗号分割),如1,3,5-12,42 
-d   delim    通过-f选项,使用delim作为定界符,上例中即使用“:”作为定界符。默认为制表符。 
-f    list      以字段为主,作剪下的操作。list为字段编号或一段范围的列表。例子中即代表取第1个和第5个。

使用join连接字段 
join命令可以将多个文件结合在一起,每个文件里的每条记录,共享一个键值key,键值指的是记录中的主字段。语法为: 
join   [option …]   file1   file2 选项: -1  field1 -2  field2 
标明要结合的字段,-1  field1指的是从file1取出field1,从file2中取field2,字段编号从1开始。 -o   file.field 
输出file文件的field字段。可以使用多个-o选项,输出多个字段。 -t  separator 
使用separator分隔符,此字符页尾输出的字段分隔符。 例子如下:





sed程序 
一般执行文本替换的程序时sed,流编辑器(Stream Editor)。一般在管道中间使用sed来执行替换操作。做法是使用s命令-要求正则表达式寻找,用替代文本(replacement text)替换匹配的文本。 
awk命令 
awk主要功能为做一些简易的文本处理,如取出字段并重新编排。语法: awk  „program’  [file …] 
awk读取命令行上指定的各个文件(若无,则为标准输入),一次读取一行记录,针对每一行,执行应用程序指定的命令。awk程序基本构架为: 
pattern  {action} 
pattern或是action都能省略。省略patter,则会对每条记录执行action,省略action怎等于{print}。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值