Linux shell
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://zxuhong.blog.51cto.com/368977/73527 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Linux shell编程1.1 shell变量为使shell编程更有效,系统提供了一些shell变量。变量可以定制用户本身的工作环境。使用变量可以保存有用信息,使系统获知用户相关设置;变量也用于保存暂时信息。
有两种变量:本地变量 和 环境变量。
(1)本地变量
本地变量在用户现在的Shell生命期的脚本中使用。
要设置一本地变量,格式为: variable-name = value or ${variable-name=value}
定义变量:可以使用export
来定义导出一变量,export variable-name=”variable-value”
显示变量:使用echo命令可以显示单个变量值,echo $variable-name
清除变量:使用unset命令清除变量,unset variable-name
显示所有变量:使用set 显示所有本地定义的shell变量;使用env显示所有shell变量。
例子:
$ export MYNAME=”hongdy”
$ echo $MYNAME
hongdy
$ env
$ set
$ unset MYNAME
(2)环境变量
环境变量用于所有用户进程(子进程),登录进程为父进程。Shell中执行的用户进程均为子进程 。最好在.profile中定义,系统在/etc/profile文件中已经设置了一些环境变量。
设置环境变量:使用export导出环境变量,export VARIABLE-NAME
显示环境变量:使用echo命令可以显示环境变量,echo
$(VARIABLE-NAME)
清除环境变量:使用unset命令清除环境变量,unset VARIABLE-NAME
显示所有环境变量:env显示所有环境变量
下面显示的是Shell的一些基本环境变量
(3)位置变量
位置参数是一种在调用shell程序的命令行中按照各自的位置决定的变量,是在程序名之后输入的参数。位置参数之间用空格分隔,shell取第一个位置参数替换程序文件中的$1,第二个替换$2,依次类推。$0是一个特殊的变量,它的内容是当前这个shell程序的文件名即脚本名。
每个访问参数前要加&符号,第一个参数为0,表示预留保存实际脚本名字。
比如向脚本传送 I love you
$0 &1 &2 &3
脚本名字 I love you
例子:
$ vi findfile
#!/bin/sh
find / -name $1 -print
$ chmod a+x findfile
$ ./findfile /etc/passwd
特定变量参数
1.2 shell输入和输出在shell脚本中,可以用几种不同的方式读入数据:可以使用标准输入—缺省为键盘,或者指定一个文件作为输入。对于输出也是一样:如果不指定某个文件作为输出,标准输出总是和终端屏幕相关联。
(1)echo
使用echo命令可以显示文本或者把字符串输入到文件。
$ echo string
\c 不换行;\t
跳格;\n 换行;
-n选项禁止echo命令输出后换行,-e使转义符生效。
(2)read
Read语句从键盘或文件的某一行文本中读入信息,并将其付给一个变量,空格作为分隔符。
(3)cat
cat是一个简单而通用的命令,可以用它来显示文件内容,创建文件,还可以用它来显示控制字符。
例子:
$ export NAME=hongdy
$ echo $NAME
hongdy
在使用cat命令时要注意,它不会在文件分页符处停下来;它会一下显示完整个文件。如果希望每次显示一页,可以使用more命令或把cat命令的输出通过管道传递到另外一个具有分页功能的命令中,比如:$ cat myfile | more
如果希望创建一个新文件,并向其中输入内容,cat命令把标准输出重定向到该文件中,标准输入是键盘,输入完毕按ctrl+D结束输入。
cat > myfile
hongdy // 输入的内容,然后回车
ctrl+d // 结束输入返回
(4)pipe
可以通过管道把一个命令的输出传递给另一个命令作为输入,管道用竖杠 | 表示。
管道一般形式为:命令1 | 命令2
比如:$ ls |
grep *.txt 在ls结果中搜索txt文件
(5)tee
tee命令作用可以用字母T来形象地表示。它把输出的一个副本输送到标准输出,另一个副本拷贝到相应的文件中。
tee命令的一般形式:tee –a files -a
表示追加到文件末尾
比如:$ ls | tee
result 将ls结果显示到标准输出,同时拷贝到文件中。
(6)重定向
标准输入是文件描述符0;标准输出是文件描述符1;标准错误是文件描述符2
$ command 1>filename //
把标准输出重定向到一个文件中
$ command > filename
2>&1 // 把标准输入和标准错误一起重定向到一个文件中
$ command < filename // 命令以filename文件作为标准输入
例子:
$ grep “hello” * >
result 2>&1
gerp 的结果将标准错误重定向到标准输出。
1.3 后台执行命令使某些进程在后台运行,也就是说不在终端屏幕上运行。后台执行命令有以下四种:
(1)cron
cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron
是Linux的内置服务,但它不自动启动,可以用以下的方法启动、关闭这个服务:
# /sbin/service crond start //启动服务
# /sbin/service crond stop //关闭服务
# /sbin/service crond restart //重启服务
# /sbin/service crond reload //重新载入配置
也可以将这个服务在系统启动的时候自动启动。
比如:在/etc/rc.d/rc.local这个脚本的末尾加上 /sbin/service
crond start
crontab命令
crontab命令的一般形式为:crontab [-u user] -e -l –r
-u 用户名;-e 编辑crontab文件;-l 列出crontab文件中的内容;-r
删除crontab文件。
cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明:
# crontab -u // 设定某个用户的cron服务,一般root用户在执行此命令的时候需要此参数
# crontab -l // 列出某个用户cron服务的详细内容
# crontab -r // 删除某个用户的cron服务
# crontab -e // 编辑某个用户的cron服务
例子:
root查看自己的cron设置:#
crontab -u root -l
root删除hongdy用户的cron设置: # crontab -u hongdy -r
在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u
root –e ,进入vi编辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >>
/tmp/ls.txt
这个格式的前一部分是对时间的设定,后面一部分是要执行的命令,如果要执行的命令太多,可以把这些命令写到一个脚本文件,然后在这里直接调用这个脚本文件,调用的时候写出命令的完整路径。
时间的设定我们有一定的约定,前面五个*号代表五个数字,数字的取值范围和含义如下:
分钟(0-59);小時(0-23);日期(1-31);月份(1-12);星期(0-6)//0代表星期天
除了数字还有几个特殊的符号就是"*"、"/"和"-"、",",*代表所有的取值范围内的数字,/代表每的意思,"*/5"表示每5个单位,"-"代表从某个数字到某个数字,
","分开几个离散的数字。
例子:
(1) 每天早上6点
0 6 * * * echo "Good morning." >>
/tmp/test.txt
(2) 每两个小时
0 */2 * * * echo "Have a rest" >>
/tmp/test1.txt
(3) 晚上11点到早上8点之间每两个小时,早上八点
0 23-7/2,8
* * * echo "Have a good dream" >> /tmp/test3.txt
(4) 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
0 11 4 * 1-3 echo "Have a rest" >>
/tmp/test4.txt
(5)
0 4 1 1 * echo "Have a rest" >>
/tmp/test5.txt
每次编辑完某个用户的cron设置后,cron自动在/var/spool/cron下生成一个与此用户同名的文件,此用户的cron信息都记录在这个文件中,这个文件是不可以直接编辑的,只可以用crontab
-e 来编辑。cron启动后每过一份钟读一次这个文件,检查是否要执行里面的命令。因此此文件修改后不需要重新启动cron服务。
at命令允许用户向cron守护进程提交作业,使其在稍后的时间运行。这里稍后的时间可能是指10
min以后,也可能是指几天以后。如果你希望在一个月或更长的时间以后运行,最好还是使用crontab文件。一旦一个作业被提交,a t命令将会保留所有当前的环境变量。
At命令
at命令的基本形式为: at [-f
script] [-m -l -r] [time] [date]
其中:
-f script 是所要提交的脚本或命令。
-m 作业完成后给用户发邮件。
-l 列出当前所有等待运行的作业。
-r 清除作业。为了清除某个作业,还要提供相应的作业标识(ID)。
time at命令的时间格式非常灵活;可以是H、HH . HHMM、HH:MM或H:M,其中H和M分别是小时和分钟。还可以使用a
. m .或p . m .。
date 日期格式可以是月份数或日期数,而且at命令还能够识别诸如today之类的词。
使用at命令提交作业有几种不同的形式:可以通过命令行方式,也可以使用a
t命令提示符。
如果你想提交若干行的命令,可以在at命令后面跟上日期/时间并回车。然后就进入了at命令提示符,这时只需逐条输入相应的命令,然后按
<CTRL-D>退出。
例子:
提交作业
# at 10:50
at> find / -name “passwd”
–print
at> <EOT>
其中<EOT>就是<CTRL-D>。
列出提交的作业
# at –l
清除作业
$atrm [job no]或 at -r [job no]
要清除某个作业,首先要执行at
-l命令,以获取相应的作业标识,然后对该作业标识使用at -r 命令,清除该作业。
当在前台运行某个作业时,终端被该作业占据;而在后台运行作业时,它不会占据终端。
可以使用&命令把作业放到后台执行。
该命令的一般形式为:命令 &
如果正在运行一个进程,而且觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令。该命令可以在你退出帐户之后继续运行相应的进程。Nohup就是不挂起的意思( no hang up)。
nohup命令的一般形式为:nohup command &
1.4 正则表达式使用shell时,从一个文件中抽取多于一个字符串将会很麻烦。例如:在一个文本中抽取一个词,它的头两个字符是大写的,后面紧跟四个数字。如果不使用某种正则表达式,在shell中将不能实现这个操作。
基本元字符集及其含义
句点“.”可以匹配任意单字符。例如:如果要匹配一个字符串,以beg开头,中间夹一个任意字符,那么可以表示为beg.n,“.”可以匹配字符串头,也可以是中间任意字符。
在行首以^匹配字符串或字符序列
^只允许在一行的开始匹配字符或单词。
在行尾以$匹配字符串或字符
可以说$与^正相反,它在行尾匹配字符串或字符, $符号放在匹配单词后。假定要匹配以单词txt结尾的所有行txt$
使用*匹配字符串中的单字符或其重复序列
使用此特殊字符匹配任意字符或字符串的重复多次表达式。例如:compu*t将匹配字符u一次或多次。
使用\屏蔽一个特殊字符的含义
有时需要查找一些字符或字符串,而它们包含了系统指定为特殊字符的一个字符。
什么是特殊字符?一般意义上讲,下列字符可以认为是特殊字符:
$ . ‘ “” [ ] ^ | () \ + ?
假定要匹配包含字符“.”的各行而“.”代表匹配任意单字符的特殊字符,因此需要屏蔽其含义。操作如下:\ . 不认为反斜杠后面的字符是特殊字符,而是一个普通字符即句点。
如果要在正则表达式中匹配以*.txt结尾的所有文件,可做如下操作: \*\.txt 即可屏蔽字符*的特定含义。
使用\{\}匹配模式结果出现的次数
使用*可匹配所有匹配结果任意次,但如果只要指定次数,就应使用\ {
\ },此模式有三种形式,即:
pattern\{n\} 匹配模式出现n次。
pattern\{n,\} 匹配模式出现最少n次。
pattern\{n,m} 匹配模式出现n到m次之间,n , m为0
- 2 5 5中任意整数。
1.5 grep全局正则表达式版本grep允许对文本文件进行模式查找,可以和正则表达式一起使用。
grep一般格式:grep [选项] 基本正则表达式 [文件]
基本正则表达式可为字符串。在grep命令中输入字符串参数时,最好将其用双引号括起来。有两个原因,一是以防被误解为shell命令,二是可以用来查找多个单词组成的字符串。
常用的grep选项:
缺省情况下, grep是大小写敏感的,如要查询大小写不敏感字符串,必须使用-i开关。
精确匹配:每个匹配模式中抽取字符串后有一个<Tab>键;使用grep抽取精确匹配的一种更有效方式是在抽取字符串后加\>。
使用正则表达式使模式匹配加入一些规则,因此可以在抽取信息中加入更多选择。使用正则表达式时最好用单引号括起来,这样可以防止grep中使用的专有模式与一些shell命令的特殊方式相混淆。
例子:
# grep –R –n –s “hongdy”
/etc
查找/etc目录下所有包含hongdy的文件。-R表示递归查找etc下的所有目录;-n 表示显示匹配行及行号;-s 表示不显示不存在或无匹配文件的错误信息。
1.6 trtr用来从标准输入中通过替换或删除操作进行字符转换,主要用于删除文件中控制字符或进行字符转换。
使用tr时要转换两个字符串:字符串1用于查询,字符串2用于处理各种转换。tr刚执行时,字符串1中的字符被映射到字符串2中的字符,然后转换操作开始。
tr命令的一般格式:tr –c –d –s [ “string_to_translate_from” ] [ “string2_translate_to
] file
-c 用字符串1中字符集的补集替换此字符集
-d 删除字符串1中所有的输入字符
-s 输出有重复出现的字符序列,只保留第一个。
(1)删除重复出现的字符
$ tr –s “[a-z]” < file 去除文件file中所有重复字母
(2)删除空行
使用-s,换行的八进制表示为\012 或使用换行速记方式 \n。
$ tr –s “[\012]” < test.txt //
使用八进制方式
$ tr –s [“\n”] <
test.txt // 使用转义字符
(3)大小写字母转换
$ echo “
$ echo “china” | tr “[a-z]
“ “[A-Z]” // 转换成大写字母
$ cat file1 | tr “[A-Z]” “[a-z]” > file2 // 将文件file1大写转换成小写并输出至文件file2
(4)删除指定字符
结合使用- c和- s选项。
$ tr –cs “[A-Z][a-z]” “[\012*]” < file // 删除文件中所有数字,只保留字母。
(5)转换控制字符
tr的第一个功能就是转换控制字符,特别是从dos向UNIX转换。
使用 cat –v 显示控制字符。
$ cat –v test.txt
Zhou ^^^^^^12^M
Xu^^^^^^50^M
Hong^^^^100^M
^Z
‘^^^^^^’ 是tab键。每一行以Ctrl-M结尾,文件结尾Ctrl-Z。
查看ASCII表,^的八进制代码是136,^M是015,tab键是01,^Z是032
$ tr –s “[\136]” “[\011*]”
< test.txt
$ tr –s “[\015\032]” [“\n”] < test.txt
1.7 sed1.7.1 sed概述sed 是一种在线编辑器,它一次处理一行内容。处理时把当前处理的行存储在临时缓冲区中,称为模式空间(pattern
space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
可以通过定址来定位你所希望编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围,如1,3表示1、2、3行,美元符号$表示最后一行。范围可以通过数据,正则表达式或者二者结合的方式确定 。在sed语句,正则表达式必须封闭在//中间。在sed地址管理中默认是对全局进行操作,地址可以分为行地址和模式地址。如1,10d 12d 10,$d 表示行地址,如/^$/d 表示模式地址。用户在进行操作时,可以对行地址和模式地址结合进行操作。
1.7.2 Sed命令调用sed命令有两种形式:
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s) 选项
-e command, --expression=command 允许多台编辑。
-h, --help 打印帮助,并显示bug列表的地址。 -n, --quiet, --silent 取消默认输出。 -f, --filer=script-fil 引导sed脚本文件名。 -V, --version 打印版本和版权信息。 (1)替换命令
语法格式:sed
‘s/old/new/flags’ file
文件file中内容old用new替换。
Flags:g表示对全局进行替换;w file:表示匹配行的内容写到另一个文件中。
例如:
$ sed ‘s/unix/Linux/g’ file
文件file中所有内容unix都用Linux替换
$ sed ‘s/unix/Linux/w
(2)删除命令
语法格式:sed ‘[address]d’
file
删除文件file中address表达的内容
例如:
$ sed ‘/^\.aa/d’ file 删除文件file中以.aa开头的内容
$ sed ‘/^$/d’ file
删除文件file中空行的内容
$ sed ‘10d’ file
删除文件file中第10行的内容。
(3)追加命令
语法格式:sed ‘[address]a\text’
file
文件file中address表达的行后面添加text内容
例如:
$ sed '
$ sed '/unix/a\abcd' file 在文件file中所有出现unix字符的行后面追加一行abcd字符
$ sed '/unix/a\abcd\n\dcba' file 在文件file中出现unix字符行后面追加两行字符:abcd和dcba。 (4)插入命令
语法格式:sed ‘[address]i\text’
file
文件file中address表达内容行前面插入text内容。
例如:$ sed
'/unix/i\abcd´ file 在文件file中unix行前面插入abcd字符
(5)更改命令
语法格式:sed ‘[address]c\text’
file
文件file中address表达内容的行用text代替。
例如:$ sed '
(6)打印行号
语法格式:sed ‘[address]=’
file
打印 文件file中address表达内容的行号
例如:
$ sed '/unix/=' file 打印文件file中包含unix字符的行号。不包含unix字符的行不打印行号。
(7)读写文件
语法格式:sed ‘[address]r
file
语法格式:sed ‘[address]w
file1’ file 文件file中address表达的内容写入文件file2中
例如:
$ sed '/unix/r
$ sed '2r 11' file 在文件file的第2行后面读入11文件的内容
$ sed '2,5w 22' file 将文件file中第2行到第5行的内容写到22文件中去。
1.8 awk1.8.1 awk概述awk是一种样式扫描与处理工具,与sed和grep很相似,但其功能却大大强于sed和grep,它几乎可以完成grep和sed所能完成的全部工作,同时它还可以可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。
awk是以三个创立者的名字(Aho、Peter Weinberg和Brain Kernighan)的缩写命名的,awk拥有自己的语言:awk程序设计语言。awk语言的最基本功能是在文件或字符串中基于指定规则浏览和抽取信息。awk抽取信息后才能进行其他文本操作。
1.8.2 Awk调用有三种方式可以调用awk
(1) awk命令行:awk [-F field-separator] ‘commands’ input-file(s) [-F 域分隔符]是可选的,awk使用空格作为缺省的分隔符;commands是真正的awk命令;input-files是一个或多个输入文件。
(2)将所有的awk命令插入一个脚本文件并以 #!/bin/awk -f 作为首行,给予该脚本可执行权限,然后在shell下通过键入该脚本的脚本名调用之。 (3) 将所有的awk命令插入一个单独脚本文件,然后使用: awk -f awk-script-file input_file(s) -f选项指明文件awk-script-file中的awk脚本,input-files是一个或多个输入文件。
awk命令的一般形式
awk ' BEGIN { actions }
awk_pattern1 { actions } ............ awk_patternN { actions } awk END { actions } 其中 BEGIN {
actions } 和 END {
actions } 是可选的。
awk脚本文件
#!/bin/awk -f
BEGIN { print "this
is the begin of awk script" }
{ print $1, $2, $3 }
END { print "this is
the end of awk script" }
第一行是!/bin/awk
-f。这很重要,没有它自包含脚本将不能执行。这一行告之脚本系统中awk的位置。通过将命令分开,脚本可读性提高,还可以在命令之间加入注释,使用“#”作为注释符,它使“#”到行尾的内容成为注释。
域和记录
awk执行时,其浏览域标记为$1、$2 . . . $n,这种方法称为域标识。使用这些域标识将更容易对域进行进一步处理。使用$ 1 , $ 3表示参照第1和第3域,注意这里用逗号做域分隔。如果希望打印一个有5个域的记录的所有域,不必指明$ 1 , $ 2 , $ 3 ,
$ 4 , $ 5,可使用$ 0,意即所有域。
例子:
$ awk -F ":" '{print $1, $3, $6}' /etc/passwd 打印passwd文件的用户名、用户ID和用户目录
$ awk '/hongdy/{print}' /etc/passwd 显示文本文件passwd含有字符串hongdy的所有行。
流程控制结构
(1)if (condition) {then-body}
[else {else-body}]
(2)while (condition) {body} (3)do {body} while (condition) (4)for (initialization; condition; increment) {body} 其中condition一般为布尔表达式,body和else-body是awk语句块。 1.8.3 awk变量在awk脚本中的表达式中要经常使用变量。不要给变量加双引号,因为awk将视之为字符串。awk的变量基本可以分为两类:awk内部变量和自动以变量。
1.8.3.1 awk内部变量awk的内部变量用于存储awk运行时的各种参数,这些内部变量又可以分为:
(1)自动内部变量:这些变量的值会随着awk程序的运行而动态的变化,在awk_script中改变这些变量的值是没有意义的(即不应该被赋值)。 常用的自动内部变量
例子:
$ awk ‘{ print “filename=” FILENAME, “count=” NF}’ 11 假设文件11内容为123 abc。
Filename=11, count=2
(2)字段变量($0 $1 $2 $3 ...)
当awk把当前输入记录分段时,会对这些字段变量赋值。在awk运行过程中字段变量的值是动态变化的。可以创建新的输出字段,比如当前输入记录被分割为8个字段,这时可以通过对变量 $9 (或$9之后的字段变量)赋值而增加输出字段,NR的值也将随之变化。
字段变量支持变量名替换。 例子:
$ pwd | awk -F/ '{print $NF}' 打印输入记录的最后一个字段
如果当前目录为/home/hongdy/linux
, awd 以/ 为分隔符,有三个字段,输入的最后一个字段为linux
$ awk '{x=2;print $x}' 11 打印输入记录的第2个字段
如果文件11的内容为zhou xu hong, 有三个字段,第二个字段即为xu
(3)其它内部变量
可以修改这些变量。常见的有:
|

