Linux 与 unix shell编程指南——学习笔记
第一章 文件安全与权限
文件访问方式:读,写,执行。
针对用户:文件属主,同组用户,其它用户。
文件权限位最前面的字符代表文件类型,常用的如
d 目录;l 符号链接;p 命名管道文件;- 普通文件 ...
用chmod改变文件权限位的设置:
chmod [who] operator [permission] filename
who: u 属主;g 同组;o 其它;
operator:+ 增加权限;- 取消权限;= 设定权限;
permission:r 读;w 写;x 执行;
目录的权限位:
读:可列出目录内容;写:可在目录中创建文件;执行:可以搜索和访问。
目录的权限将会覆盖该目录中文件的权限。
suid和guid:其它用户在执行脚本时也有属主/用户组的权限。
查找具有suid和guid权限的文件:$ ls -l | grep '^...s..s'。
chown -R -h owner file,-R 递归操作子文件;-h 不改变符号链接文件的目标文件。
umask命令拿走缺省模式下的默认权限。
创建软链接:ln [-s] source_path target_path。
在新安装的系统中,有时需要ln -s /tmp /var/tmp,因为有些应用程序认为存在/var/temp目录。
谨慎使用:chmod -R,一旦设置错误又没有备份,几乎不可能恢复。
不要以根用户身份设置suid。
第二章 使用find和xargs
Find工具:可以遍历当前目录甚至于整个文件系统来查找某些文件或目录。
一般形式:find pathname -options [-print -exec -ok]
例子:find /etc -name "host*" -print
例子:find / -mtime -5 -print
例子:find /etc -name "passwd*" -exec grep "rounder" {} \;
Xargs命令:每次只获取一部分文件而不是全部。
例子:find . -name "core" -print | xargs echo "" > /tmp/core.log
例子:find /apps/audit -perm -7 -print | xargs chmod o-w
例子:find / -type f -print | xargs grep "device"
find命令是一个非常优秀的工具,它可以按照用户指定的准则来匹配文件,使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。
第三章 后台执行命令
目标:使进程在后台运行,而你依然可以使用终端。
四种主要方式:cron,At,&和Nohup。
cron:系统主要的调度进程,可以在无需人工干预的情况下运行作业。
crontab文件格式:分_时_日_月_星期_要运行的命令。
crontab命令:crontab -u(用户名) -e(编辑) -l(列出内容) -r(删除)。
crontab文件用#表示注释,最后的命令必须写绝对路径。
at:用户向cron进程提交作业,在稍后的时间运行。
基本形式:at [-f script] [-m -l -r] [time] [date]
at命令提示符方式,提交若干行系统命令。
at支持的时间格式非常灵活,例如 at now + 10 minutes。
提交脚本:at 3.pm tomorrow -f /apps/bin/db_table.sh。
&命令:当在后台运行作业时,它不会占据终端。
一般形式:命令 &。
将后台输出重定向:command >out.file 2>&1 &。
用ps命令查看进程:ps -ef|grep 200205。
使用此方法,退出时进程将会终止。
nohup命令:不挂起,即退出账户后继续运行相应的进程。
缺省情况下输出重定向到nohup.out文件中。
重定向输出:nohup command > myout.file 2>&1。
总结:Cron和其它工具可以使系统管理任务变得更轻松。
第4章 文件名置换
Shell提供完整的字符串模式匹配规则,称之为元字符。还可以使用字符类型来匹配文件名。
使用*匹配文件名中的任何字符串,例如*.doc。
使用?匹配文件名中的任何单个字符,例如conf.??.log。
使用[...]匹配方括号[]中的任何字符,可以用横杠-表示范围,例如:
i或o开头的文件:[io]*
log.开头,后跟一个数字的文件:log.[0-9]*
大写开头的文件:[A-Z]*
隐藏文件:.*
使用[!...]匹配方括号[]中非感叹后!之后的字符。
总结:使用元字符可以大大减少查找文件名上的工作量,这是一种非常有效的模式匹配方法。
第5章
shell输入与输出
本章讨论标准输入,标准输出及标准错误,并介绍如何重定向标准输入和输出。
一 echo命令可以显示文本或变量,或将字符串输入到文件。
Linux下使用-e让转义符生效,如\n代表换行。
echo可以输出变量如$HOME,也可用抑音符执行命令,如`tty`。
使用重定向>, 或者追加>>,将字符串输出到文件。
二 read语句从键盘或文件的某一行文本中读入信息,并赋值给一个变量。
当read只指定一个变量,它会将所有的输入赋给该变量,直到遇到回车。
多个变量用空格分隔,超长文本归最后一个变量。
在脚本中可用如下方式提示用户输入:
echo -e "your name:\c"
read name
三 cat命令可以用来显示文件内容,创建文件,还可以显示控制字符。
cat命令不会分页,如果希望分页可用 cat filename|pg。
cat创建文件并编辑:cat > newfile, 输入内容,CTRL-D结束。
四 管道|,把一个命令的输出传递给另一个命令作为输入。
显示用户名和所在终端:who|awk '{print $1"\t"$2}'。
列出文件系统:df -k|awk '{print $1}'|grep -v "Filesystem"。
上面命令还可以这样df -k|awk '{print $1"\t"$2}'|grep -v "Filesystem"|sed s'/\/dev\///g'。
五 tee命令,看到输出的同时也将其存入文件。
一般形式:tee -a filename,其中-a表示追加到文件末尾。
六 标准输入、输出和错误
文件描述符:0、1、2分别代表标准输入、输出和错误。
文件重定向,可以指定命令的标准输入、输出和错误。常用重定向命令如下:
command << delimiter 从标准输入读入,直到遇到分解符;
command > filename 2 > &1;
command < filename >filename2;
command > &m (标准输出重定向到文件描述符m中);
用户名排列:cat passwd|awk -F: '{print $1}'|sort 1>sort.out。
创建空文件>filename。
七 exec命令可以替代当前shell;exec只有在对文件描述符进行操作时,才不会覆盖当前的shell。
可以使用exec命令通过文件描述符打开和关闭文件
总结:重定向是shell中的一个重要部分,通过重定向,可以指定命令的输入;如果有错误的话,可以用一个单独的文件记录下来,便于快捷地查找问题。
第六章
命令执行顺序
本章主要讨论命令执行控制和命令组合。
一 使用&&
一般形式:命令1&&命令2。
左边的命令执行成功,才执行右边的命令。
例子:mv /apps/bin /apps/dev/bin && rm -r /apps/bin。
二 使用||
一般形式:命令1||命令2。
如果左边的命令执行失败了,就执行右边的命令。
三 用()和{}将命令结合在一起
在当前shell中执行一组命令:(命令1;命令2;...)。
在子shell中执行:{命令1;命令2;...}。
例子:sort money.txt > money.sorted && (cp money.sorted /logs/money.sorted;lp money.sorted)。
小结:在编写shell脚本时,使用&&和||对构造判断语句非常有用。可以根据&&或||前面命令的返回值来控制其后面命令的执行。
第七章
正则表达式介绍
当从一个文件或命令输出中抽取或过滤文本时,可以使用正则表达式(RE),正则表达式是一些特殊或不很特殊的字符串模式的集合。
本章只介绍以字符出现情况进行匹配的基本元字符,包括:
^ $ * [] \ . pattern\{n\} pattern\{n, \} pattern\{n, m\}
(备注:以上基本元字符在vim中也可以使用,注意*和\+的区别)
一 使用句点匹配单字符。
在 ls -l 命令中,可以匹配一定的权限:...x..x..x 。
二 在行首以^匹配字符串或字符序列。
在 ls -l 命令中,可以用^d来匹配目录。
^在正则表达式中频繁使用,因为大量抽取操作通常在行首。
三 在行尾以$匹配字符串或字符。
匹配空行:^$ 。
四 使用*匹配字符串中的单字符或其重复序列。
五 使用\屏蔽一个特殊字符的含义。
六 使用[]匹配一个范围或集合。
可以用逗号将括号内字符分开,但并不强制要求这样做。
匹配任意数字:[0-9] 。
匹配任意字母:[A-Za-z] 。
当^用在括号里,指否定或不匹配括号里的内容。
匹配任意非数字型字符:[^0-9]。
七 使用\{\}匹配模式结果出现的次数。
pattern\{n\} 匹配模式出现n次。
pattern\{n,\} 匹配模式出现最少n次。
pattern\{n,m\} 匹配模式出现n到m次之间。
(备注:pattern\{,m\}应该也是可以的)
在写正则表达式时,可能会有点难度或达不到预期结果,一个好习惯是在写真正的正则表达式前先写下预期的输出结果。这样做,当写错时,可以逐渐修改,以消除意外结果。
小结:在shell编程中,一段好的脚本与完美的脚本间的差别之一,就是要熟知正则表达式并学会使用它们。相比较起来,用一个命令抽取一段文本比用三四个命令得出同样的结果要节省许多时间。
第八章 grep 家族
grep是Linux中使用最广泛的命令之一,它允许对文本文件进行模式查找。grep有三种变形:Grep,Egrep和Fgrep。
一 grep的一般格式:grep [选项] 基本正则表达式 [文件]。
二 双引号引用
输入字符串参数应用双引号,防止被误解为shell命令或文件。
调用变量应该用双引号,否则没有返回结果。
调用模式匹配应该用单引号。
三 常用grep选项
-c, -i, -h, -l, -n, -s, -v。
其中-c显示总匹配行数,-n显示行序号,-v显示所有不匹配行,-i大小写不敏感。
四 查询多个文件
grep "sort" *.doc。
grep "sort it" *。
五 精确匹配,例如:grep '48\>' data.f。
六 模式匹配,可以使用模式匹配在搜索时加入一些规则。例如:
grep '[Ss]ept' data.f | grep 483 。
grep '^[0-9][0-5][0-6]' data.f 。
加-E参数可使用扩展模式,如 grep -E '216|219' data.f 。
七 grep允许使用国际字符模式匹配或匹配模式的类名形式,例如[[:space:]]。
八 使用grep命令获取系统信息。
ls -l | grep '^[^d]' 。
ls -l | grep '^d.....x..x' 。
ps -ef | grep named | grep -v "grep" 。
九 使用egrep。
egrep使用-f开关可以将一个文件作为参数。
egrep '(3ZL|2CC)' data.f 。
who | egrep (louise|matty|pauline) 。
egrep '(shutdown | reboot)(s)?' *
小结:grep是shell编程中很重要的工具,如果要通过文件快速查找字符串或者模式,grep是一个很好的选择。
第九章 AWK介绍
awk是所有shell过滤工具中最难掌握的,本章注重于讲述使用awk执行行操作以及怎样从文本文件和字符串中抽取信息。完整的awk脚本通常用来格式化文本文件中的信息。
一 调用awk
awk [-F field-separator] 'commands' input-file(s)
awk -f awk-script-file input-file(s)
二 awk脚本
awk脚本由各种操作和模式组成。
awk脚本默认空格为域分割符,域编号从1开始。
三 模式和动作:任何awk语句都由模式和动作组成
模式部分决定动作语句何时触发及触发事件。包含BEGIN和END两个特殊字段。
实际动作在{}内指明,如果不指明,awk默认打印所有浏览记录。
四 域和记录
域标识:$1,$2...$n;$0指所有域。
保存输出:$awk '{print $0}' grade.txt | output.file。
五 条件操作符
~匹配正则表达式,!~不匹配正则表达式。
条件语句用()括起来,例如:{if($4~/brown/) print}。
简写:$awk '$0 ~ /Brown/' grade.txt。
精确匹配:$awk '$3=="48" {print $0}' grade.txt。
设置大小写:$awk '/[Gg]reen/' grade.txt。
复杂表达式:模式间通过&&,||,!互相结合起来的表达式。
六 awk内置变量
ARGC 命令行参数个数。
FS 设置输入域分隔符,等价于命令行-F选项。
打印记录个数:$awk 'END {print NR}' grade.txt。
显示目录名:$echo $PWD | awk -F/ '{print $NF}'。
七 awk操作符
设置有意义的域名 name=$n。
$awk '{if($1=="J.Troll") {$1="J.L.Troll";print $1}}' grade.txt。
创建新域,例如{$4=$2+$3}。
$awk '{(tot+=$6)}; END {print "total points :" tot}' grade.txt。
八 内置的字符串函数
gsub 替换字符串。
index 查询字符串中子串出现的第一位置。
length 返回所需字符串长度。
match 测试字符串是否包含查找字符串。
split 将字符串划分为字符串数组。
sub 发现并替换模式第一次出现位置。
substr 按照起始及长度返回字符串的一部分。
九 awk输出函数printf
$echo "65" | awk '{printf "%c\n",$0}'。
十 向一行awk命令传入参数
$who|awk '{if($1==user) print $1,$2}' user=$LOGNAME。
十一 awk脚本
awk脚本以!/bin/awk -f 开头。
在脚本中指定分隔符 BEGIN{FS=":"}。
十二 awk数组
打印数组 For (element in array) print array[element]。
总结:awk是shell编程的一个重要工具。在shell命令中,虽然可以使用awk强大的文本处理能力,但是并不要求你成为这方面的专家。
第十章 sed用法介绍
sed是一个非交互性文本编辑器,必须通过行号或正则表达式指定要改变的文本行。
和grep与awk一样,sed是一种重要的文本过滤工具,或者使用一行命令或者使用管道与grep与awk相结合。
一 调用sed的方式
sed [options] command inputfile;
sed [options] -f sedscript inputfile;
sedscript [options] inputfile;
二 保存sed输出
$sed command inputfile > outputfile;
三 sed在文件中查询文本的方式
x 匹配第x行;
x,y 匹配从x到y行;
/pattern/ 查询包含模式的行;
四 基本sed编辑命令
p 打印匹配行;
= 显示文件行号;
a\ 在定位行号后附加新文本信息;
i\ 在定位行号后插入新文本信息;
s 使用替换模式替换相应模式,等等;
五 基本sed编程举例
打印第二行: $sed -n '2p' inputfile;
打印匹配行: $sed -n '/pattern/p' inputfile;
模式和行号: $sed -n '4,/pattern/p' inputfile;
匹配元字符: $sed -n '/\$/p' inputfile;
打印末行: $sed -n '$p' inputfile;
打印匹配行及行号: $sed -n -e '/pattern/p' -e '/pattern/=' inputfile;
删除一到三行: $sed '1,3d' inputfile;
替换模式: $sed 's/oldPattern/newPattern/' inputfile;
全局替换: $sed 's/oldPattern/newPattern/g' inputfile;
将替换结果写入文件: $sed 's/oldPattern/newPattern/w sed.out' inputfile;
使用替换修改:$sed -n 's/pattern/"Hello" &/p' inputfile;
六 创建sed脚本
#!/bin/sed -f
/patten/ a\
Add this line when there is a match.
七 将sed结果写入文件命令
$sed '1,2 w sed.out' inputfile;
八 从文件中读文本
$sed '/pattern/r extrafile' inputfile;
九 匹配后退出
$sed '/pattern/q' inputfile;
十 显示文件中的控制字符
$sed '1,$l' inputfile;
小结:sed是一个强大的文本过滤工具,使用sed可以从文件或字符串中抽取所需信息。如果使用sed对文件进行过滤,最好将问题分成几步,分布执行,且边执行边测试结果。经验告诉我们,这是执行一个复杂任务的最有效方式。