|
单元五实验
文件访问权限
估计用时:30分钟
目标:熟悉多个修改文件权限命令的语法和应用,并可组合命令以完成一般的任务。
实验前准备:一台安装好的系统,其上有student 帐号。
实验1:定义文件的访问权限的实践
任务:
1、写下文件权限的字串(类似rwxr-xr-x):
664:_______________________
755:_______________________
000:_______________________
711:_______________________
700:_______________________
777:_______________________
555:_______________________
705:_______________________
111:_______________________
600:_______________________
731:_______________________
2、一个文件权限为755,哪条命令可以将其权限改为r-xr--r--?
________________________________________________________
3、你刚从Internet上下载了一个值得信任的执行文件。在你运行它之前你必须做什么?写下
两种不同的途径。
______________________________________________________
______________________________________________________
4、你在之后的单元中将会学到进程(系统中运行的程序)是被用户和用户组所拥有的,就像
文件和目录一样。一个进程只有当它的拥有者和拥有者组拥有相应的权限时,它才可以读、写
并执行一个文件或目录。
Red Hat Linux 系统通常配置成由用户apache 和组apache 运行apache Web服务器进程。
在系统安装的时候该用户和组已经作为apache 的一部分已经建立。
假设你有一个目录结构 /home/student/archive 里面有许多的文件和目录,都被设置为权
限700。你想将archive 目录在Internet 上设置为可访问的,但是当前的许可并不允许web服
务器(以用户apache 运行)访问文件。使用chmod 命令,你如何用一条命令改变文件的访问
权限?
_______________________________________________________
实验2:使用umask 设置新建文件的默认访问权限。
任务:
1、登录
2、查看当前的umask
$ umask
3、创建几个文件和目录,看看它们的访问权限
$ touch umtest1
$ touch umtest2
$ mkdir umtestdir1
$ ls -ld um*
4、改变你的umask 为一个更安全的设置,然后新建文件与目录,再比较一下访问权限
$ umask 066
$ touch umtest3
$ touch umtest4
$ mkdir umtestdir2
在查看访问权限之前,你觉得它们的权限会是多少?
____________________
____________________
____________________
$ ls -ld um*
单元六实验
Linux 文件系统基础
估计用时:1小时30分钟
目标:形成对Linux 文件系统的更充分的理解,包括:建立和使用link,使用mtools 包以处
理DOS 文件系统,使用slocate 和find,并将文档打包和压缩。
实验前准备:一台装有Red Hat Linux 系统的机器,你在实验2中需要一张空白软盘。
实验1:建立并使用link
任务:
1、在早先的实验中,你应该拷贝了/usr/share/dict/words 到你的帐号——student 的home
目录中,并命名为words。当时,这样做的原因是为了使你访问这个文件更简单。现在,我们
使用link 来达到同样的效果。
2、为了避免原来的文件和拷贝文件的混淆,我们删除words 文件的拷贝。
$ cd
$ rm words
3、如果这时候你还没有意识到的话,你早些使用的/usr/share/dict/words 实际上是一个
soft link。列出/usr/share/dict,看看link 和它的指向:
$ ls -l /usr/share/dict
total 404
-rw-r--r-- 1 root root 409305 Apr 3 10:29 linux.words
lrwxrwxrwx 1 root root 11 Apr 20 17:33 words -> linux.words
a、你如何知道它是一个soft link?
b、为什么文件的大小是11字节?
c、words对所有用户开放所有的访问权限。这会对linux.words 产生什么样的影响?除了root
用户能通过这个link 向linux.words 写数据吗?
4、再次列出文件,这次显示它们所对应的inode。它们是否拥有相同的inode?
$ ls -i /usr/share/dict
5、现在在你的home 目录中建立一个symbolic link 和一个hard link,指向
/usr/share/dict/linux.words:
$ ln -s /usr/share/dict/linux.words soft
$ ln /usr/share/dict/linux.words hard
6、测试你的新link 指向的数据:
$ head hard soft
7、用下面的命令测试你建立的link,并回答下列问题:
$ ls -il hard soft
$ stat hard soft
写出文件hard 的大小________,和soft 的大小_________。
hard 确实使用的数据块________,soft确实使用的数据块__________。
你如何解释这两个文件在数据块数上的不同?
hard 的link 数________,soft 的link 数__________。
hard 的 UID和GID__________,soft的_____________。
文件hard 由root 所拥有,并对其他用户只开放读权限。student 用户是否可以删除这个新建
的文件?为什么?
8、挑战:
a、你能建立一个symbolic link 指向一个不存在的文件吗?在这种情况下ls 命令是否给出任
何提示?
b、你能建立一个hard link 指向一个不存在的文件吗?为什么?
c、你能建立一个hard link 指向一个soft link 吗?如果你这样做的话会出现什么情况?
d、在建立了几个hard link 之后,你如何找出“真正”的文件?这个问题有意义吗?(换句
话说,有没有比你建立hard link 更“真实”的文件?)
实验2:使用mtools 包(省略)
实验3:使用find
任务:
设计并执行满足下面条件的find 命令。当你执行时递归搜索到一些你没有读权限的子目录时
你可能会遇到一些"ermission denied"消息,别去管它。你也可以在末尾加上2> /dev/null
来消除这些错误消息的影响。
第一个问题的答案已经给出,执行它,并把其他的完成。你可能需要翻看man page,并记住使
用/string 来搜索你需要的字串。如果你哪里卡住了,你可以翻看在实验4后列出的答案。
1、列出在/var/lib下games 用户拥有的所有文件
$ find /var/lib -user games 2> /dev/null
2、列出在/var 下root 用户和mail 组所拥有的所有文件
______________________________________________________
3、以"ls -l"风格列出在系统上所有不被root 或者bin 或者student 用户所拥有的文件
______________________________________________________
4、以"ls -l"风格列出/usr/bin 下所有大于一百万个字符的文件
_______________________________________________________
5、对/etc/mail 下所有的文件执行file 命令
_______________________________________________________
6、以"ls -l"风格列出/tmp 下为student 用户所拥有的“普通”文件(regular files)
_______________________________________________________
7、添加上面的命令使得以"ls -l"风格列出/tmp 下为student 用户所拥有的“普通”文件
(regular files),并且它们的修改时间在一天之前
________________________________________________________
8、改变上面的命令使得删除在/tmp 下为stduent 用户所拥有的“普通”文件(regular
files),并且它们的修改时间在一天之前。并且在每个文件删除之前都提示是否删除。
_________________________________________________________
实验4:归档和压缩
假设:
你的主硬盘在你每次使用它的时候发出可怕的声音,你估计它快完蛋了并且会将你珍贵的资料
一起带入坟墓。考虑到上次的系统备份是2年半之前,你决定备份一些对于你来说至关重要的
文件。/tmp 目录是位于另外一个物理硬盘上的分区,所以你会暂时将你的文件备份到那里。
(然而,tmpwatch 进程会将/tmp 目录中10天没有访问过的文件删除,你最好不要在那里把你
的重要文件存放过长时间。)
任务:
1、使用find 查找/home 下所有被student 所拥有的文件,然后将这些文件名传给tar 并把它
们存储在/tmp 中。
$ find /home -user student -exec tar rvf /tmp/backup.tar {} \;
2、将/etc 内的内容存储在/tmp 中的另外一个tar 文件中:
$ tar cvf /tmp/confbackup.tar /etc
3、列出两个新文件并记录它们的大小:
$ ls -lh /tmp/*.tar
backup.tar 文件的大小_________。
confbackup.tar 文件的大小_________________。
4、使用gzip 来压缩你的归档文件。然后记录新的文件大小:
$ cd /tmp
$ gzip *.tar
$ ls -lh *tar*
backup.tar.gz 文件的大小______________。
confbackup.tar.gz 文件的大小__________________。
5、解压这些文件,并重新将它们用bzip2压缩,并记录新的文件大小:
$ gunzip *.gz
$ ls -lh *tar
$ bzip2 *tar
$ls -lh *tar*
backup.tar.bz2 文件大小________________。
confbackup.tar.bz2 文件大小_________________。
6、在一个传统UNIX系统上,归档文件并压缩归档的步骤是分开的,就像你前面所做的那样。
在一个Linux 系统上,使用GNU tar 命令,tar 文件可以在建立文件的同时自动地进行一系列
不同的压缩。试试下面的步骤。tar 命令会输出一些错误信息,因为非特权用户在/etc 目录
下对一些文件没有读权限。在本实验中,可以忽略。
$ rm confbackup.tar.bz2
$ tar cfz test1.tgz /etc
$ tar cfj test2.tbz /etc
$ file test*
完成:你导入的文件已经在/tmp 目录下安全地归档、压缩并备份了。
实验3答案:
2、find /var -user root -and -group mail 2>/dev/null
3、find / -not -user root -and -not -user bin -and -not -user student -ls
2>/dev/null
4、find /usr/bin -size +1000000c -ls
5、find /etc/mail -exec file {} \;
6、find /tmp -user student -ls 2>/dev/null
7、find /tmp -user student -and -mtime +1 -and -type f -ls 2>/dev/null
8、find /tmp -user student -and -mtime +1 -and -type f -ok rm {} \;
单元七实验
bash shell
估计用时:45分钟
目标:掌握定制bash shell的技术,包括创建定制的aliase。
实验前准备:一台装有Red Hat Linux 的机器
实验1:使用aliase
任务:
1、你决定创建一个aliase,使得当你键入cls时,系统会运行clear 命令清除屏幕。由tty1
登录student 开始,然后输入并测试你得aliase。
$ alias cls='clear'
$ alias
$ cls
2、该aliase当你注销后再行登录时变得无效。为了保证每次student 登录时都可用,执行以
下步骤:
$ cd
$ pico .bashrc
找到包含#User specific aliases and functions 这一行,在这行下加上你的aliase:
alias cls='clear'
保存文件后退出。
3、注销后测试你的改动,重新在tty1 登录,并键入:
$ alias
$ cls
4、现在参考ls 的man page,建立一个叫lr 的aliase,调用ls 的5个开关。测试并加入
aliase 进你的.bashrc 文件。该aliase 应具备:
a、长格式列出
b、列出以'.'开头的文件
c、"classify" files by appending each entry
d、隐藏文件名内的控制字符
e、按修改时间排序
结果:
得到一个含有新aliase 用于清屏,和一个以时间排序ls的aliase。
实验2:改变bash 提示符
假设:
你决定定制你的bash 提示符以显示当前目录的完整路径和shell的历史数目,并作点相应的美
化。
任务:
1、在一个终端窗口,显示当前提示符字串的值。注意提示符内的静态ASCII 字符和反斜杠(
忽略符)。
$ echo $PS1
2、改变你的提示符为只显示一串静态的字串:
$ PS1='Red Hat Linux -> '
3、那不是很有用,所以恢复成原来传统的提示符-美元符,接着主机名:
$ PS1='\h $'
4、在主机名和$之间插入bash 历史提示符\!。确认在每个中间都有一个空格。
5、现在参考bash 的man page,查询代表当前目录的特殊字符。(查找PROMPTING,并注意:
你要找的是表示完整路径的特殊字符,而非像默认提示符那样的最后一个目录名)将该特殊字
符插入你的PS1 提示符字串,并前缀一个冒号。
6、你定制的提示符应该像下面这个例子一样。如果不是,继续做。
station1:/home/student 21 $
7、在你的.bashrc 中编辑你的PS1 定义,然后打开一个新的终端窗口以确认你的新提示符正
常工作。
实验3:配置shell 选项
假设:
你将使用set 和shopt 来定制你的bash shell 环境。
任务:
1、在tty1 以student 登录。查看当前配置过的shell 选项:
$ set -o
2、注意当前的ignoreeof 选项为关(off)。按<ctrl-d> 来确认这个操作,看你是否注销了。
3、以student 重登录到tty1 并执行下面的语句,然后测试 ignoreeof 选项:
$ set -o ignoreeof
$ <ctrl-d>
$ Use "logout" to leave the shell
$ set +o ignoreeof
$ <ctrl-d>se
4、现在使用shopt 命令查看其他的shell 选项:
$ shopt
5、设置并测试 cdspell 选项(注意,看清楚以下命令中故意的拼写错误):
$ cd
$ mkdir test_directory
$ cd test_driectoy
bash: cd: test_driectoy: No such file or directory
$ shopt -s cdspell
$ cd test_driectoy
test_directory
$ pwd
/home/student/test_directory
$ cd ..
$ shopt -u cdspell
$ cd test_driectoy
bash: cd: test_driectoy: No such file or directory
6、你现在看到当你试着从一个shell 提示符执行命令,你可能是在运行:一个外部可执行文
件、一个内建的shell 命令、一个aliase或者一个shell 函数等等。有时候检查你输入的命令
究竟是执行了什么是很重要的。使用内建的type 命令询问shell 究竟是执行了什么类型的命
令:
$ type cat
cat is hashed (/bin/cat)
$ type cls
cls is aliased to 'clear'
$ type shopt
shopt is a shell builtin
$ type while
while is a shell keyword
结果:
对一些shell 选项有了进一步的了解。
实验4:命令替换
1、检测当在shell 提示符下键入sawfish 的命令的全路径。使用shell 的快捷方式重新执行
那条命令,加上-ui 使得运行sawfish-ui,然后使用另一种快捷方式使运行sawfish-themer。
$ which sawfish
$ which <ESC>.-ui
$ ^ui^themer
2、以sho 为开头,重复最后一个命令。
$ <ctrl-r>sho<return>
3、当一个命令包括了另一条以backquote(``)包围起来的命令,bash 先执行包围起来的命令
,然后在整个命令执行之前将结果替换在``里面。
使用这种技术执行ls -l 列出一个特定目录,该目录是当nautilus 在shell 提示符下输入时
程序所在的路径。记住which nautilus 是先被执行的,然后它的结果替换在命令行上,然后
ls -l 在结果上执行。
$ ls -l `which nautilus`
挑战实验:使用shell 函数
任务:
1、在bash shell 提示符下,打入下列行以建立一个简单的shell 函数:
$ lsbytesum()
>{
> TotalByes=0;
> for Bytes in $(ls -l | grep "^-" | cut -c34-42);
> do
> let TotalBytes=$TotalBytes+$Bytes;
> done;
> TotalMeg=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc);
> echo -n "$TotalMeg"
>}
2、检验你新建的函数是否有效:
$ set
...output omitted -- your new function near the bottom...
$ lsbytesum()
{
TotalByes=0;
for Bytes in $(ls -l | grep "^-" | cut -c34-42);
do
let TotalBytes=$TotalBytes+$Bytes;
done;
TotalMeg=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc);
echo -n "$TotalMeg"
}
... complete prompt shown to demonstrate change to prompt ...
[student@station1 student]$ PS1="[\u@\h:\w (\$(lsbytesum) MB)]\$ "
[student@station1:~ (11.971 MB)]$ cd /bin
[student@station1:~ (.476 MB)]$ cd /sbin
[student@station1:~ (.587 MB)]$ cd /etc
[student@station1:~ (.124 MB)]$
3、挑战性问题:
1、要将该函数在每次登录时载入,你需要哪些步骤?
2、要将该函数转换为一个简单的shell script,需要哪些步骤?
结果:
得到一个新的显示当前目录中所有文件总数的shell 提示符。
单元八实验
标准输入输出和管道
估计用时:30分钟
目标:熟悉Red Hat Linux 系统上的标准输入输出和管道实现。
实验前准备:一台装有Red Hat Linux 系统的机器。
实验1:标准输入和输出
任务:
1、打开你平常使用的文本编辑器并建立两个文件:
packages1.txt 应该含有下列8行:
apache
galeon
mozilla
postgresql
procinfo
rpmfind
sawfish
squid
packages2.txt 应该含有下列6行:
anaconda
openssh
gnome-core
samba
sendmail
xscreensaver
2、cat 是Linux 最简单的文本过滤器(filter)。它的工作就是将它的输入——作为它的一个
参数的文件名,或者是从标准输入中输入,并且输出不变地输出它到标准输出。
用packages1.txt 来测试cat:
$ cat packages1.txt
3、如果cat 后没有跟参数,它就期待从标准输入的输入。这意味着如果你键入cat 后按回车
,似乎什么事也没发生。实际上,cat 在耐心的观察标准输入,等待输入的到达。如果你打入
一些字符并按回车键,cat 将你输入的送到标准输出——即原封不动的将你的输入送出。结束
cat 命令,按<ctrl-d>。这是通用的输入结束信号。
$ cat
Type some sample text, then press return.
<ctrl-d>
4、多数Linux 文本进程命令都以过滤器实现(filter),这意味着它可以从标准输入读出,然
后对它做一些事,然后送到标准输出。这些命令和cat 很像,但是它们的输出和输入不同。
本单元介绍过的tr,就是这样一个filter。如果你给tr 两个字串作为参数,那么它从标准输
入中读出,然后从第一个字串的字母到第二个字串中的字符进行翻译,然后将翻译后的字串写
到标准输出中。
重复前一个例子,改用tr。给出的参数将元音字母从小写改为大写。
$ tr 'aeiou' 'AEIOU'
Type some sample text, then press return.
<ctrl-d>
5、要告诉shell 程序的输出不要送到标准输出,而是要重定向到一个文件,那么使用重定向
符 >
重复第一个cat 的例子,重定向标准输出到packages1.catfile。这将创建一个packages1.txt
的拷贝。cat 这个输出文件,并且用diff 和ls 检验它是否和原先的文件拥有相同的内容。
$ cat packages1.txt > packages1.catfile
$ cat packages1.catfile
$ diff packages1.txt packages1.catfile
$ ls -l packages1*
6、在一个已存在的文件中追加内容,使用>> 操作符。
在packages1.catfile 后追加packages2.txt 的内容,并且检验结果
$ cat packages2.txt >> packages1.catfile
$ cat packages1.catfile
7、如果没有文件名作为参数给cat,并且标准输出(原书写standard input,我觉得错了)定
向为一个文件,那么屏幕上打的任何字符直到按下<ctrl-d>,将会被重定向到那个文件。这种
方法可以很容易建立一个新文件。
$ cat > typedin.txt
This time , when text is typed at the keyboard,
It is not echoed back to the screen,
It is instead redirected to the file typedin.txt
<ctrl-d>
$ ls -l typedin.txt
$ cat typedin.txt
8、重复前面的步骤,替换cat 为tr 命令。
$ tr 'aeiou' 'AEIOU' > trfile.txt
This time , when text is typed at the keyboard,
It is not echoed back to the screen with the translation made,
It is instead redirected to the file trfile.txt
<ctrl-d>
$ ls -l trfile.txt
$ cat trfile.txt
9、使用set -o 显示当前bash 的noclobber 选项。检验当重定向输出到一个文件时你的确可
以“修补(clobber)”该文件。
$ set -o
$ ls -l /tmp > trfile.txt
$ ls -l trfile.txt
$ cat trfile.txt
10、使用set 修改noclobber 选项,然后检验操作:
$ set -o noclobber
$ echo "new contents" > trfile.txt
bash: foo: cannot overwrite existing file
11、cat 可以接受一个文件名,或者一个重定向的文件作为标准输入。测试下面两个命令:
$ cat packages1.txt
$ cat < packages1.txt
12、然而,tr 不允许文件名作为参数,它需要从标准输入的输入。
$ tr 'aeiou' 'AEIOU' < packages1.txt
13、标准输出和输入可以同时被重定向,就像下面这个例子。和上面一样,从packages1.txt
定向输入到tr,但是这次需要重定向输出。屏幕上没有输出——它输出到了文件
packages1.trfile.txt。
$ tr 'aeiou' 'AEIOU' < packages1.txt >pacakges1.trfile.txt
$ ls -l packages1.txt packges1.trfile.txt
$ cat packages1.trfile.txt
实验2:管道
1、为了将标准输出从一个命令定向到另外一个命令作为标准输入,引入了一种叫做管道的特
殊的重定向机制。
若没有管道,打印一个目录列表,至少需要两步——而且还有一个文件作为打印后没用的副产
品。需要第三步来删除它。(注意,这些步骤当你没有打印机时仅作演示使用)
$ ls -l > /tmp/ls.txt
$ lpr /tmp/ls.txt
$ rm /tmp/ls.txt
如果使用管道,这三步可以在一个短命令中完成——并且不需要建立临时文件、再删除。注意
lpr 从标准输入中得到输入,所以没有必要加任何参数。
$ ls -l | lpr
2、管道经常用于一个可能生成多行的命令,输出到less。命令执行的顺序是从左开始。当输
出生成后,通过管道传到在右边等待的命令。less 从一个管道中等待输入,所以不需要加任
何参数。(用空格键翻页,然后按q退出)
$ ls -l /usr/bin | less
实验3:练习
如果你需要答案,答案在后面列出。但请用本单元提供的信息和man page努力完成这些练习。
1、为命令cal 在你的home 目录下建立一个格式化的man page 拷贝,文件名为cal.man
2、用哪个单条命令可以配置你的输入是键盘输入、输出是打印机输出?
3、你如何将/usr/bin 下的名字以'c'或者'd'开头的文件长列表输出到打印机?
实验3答案
2、lpr
lpr 若给出文件名作为参数,则它打印文件内容。如果没有文件名给出,则它从标准输入读入
数据。当你按<ctrl-d>后你从键盘输入的数据将被打印出来。
3、ls -l /usr/bin/[cd]* | lpr
单元九实验
字符处理
估计用时:60分钟
目标:熟悉几种Red Hat Linux 上的字符处理程序。
实验前准备:一台装有Red Hat Linux 的机器,并在你的home 目录中有/etc/passwd 的拷贝
。
实验1a:基本字符处理
任务:
1、拷贝/etc/passwd 到你的home 目录
$ cd
$ cp /etc/passwd .
2、每个帐号都会在/etc/passwd 中占有一行。使用wc 统计passwd 文件的行数。
$ wc -l passwd
你系统上的帐号数有_______个。
3、生成一个用户shell 列表并将它存在另一个文件中:
$ cut -d: -f7 passwd > shells
4、使用cat 查看你的shells 文件。你将感到虽然文件存储了信息但是组织得不理想。将这些
行排序并输出到一个新文件:
$ sort shells > sorted.shells
5、你的文件包含了多个重复的值。使用uniq 来统计每个值出现多少次:
$ uniq -c sorted.shells > uniq.sorted.shells
为什么在传给uniq 之前必须先要将输出排序?
(提示:试试uniq -c shells 和 man uniq)
6、要生成一个数字逆序排列的,你机器上使用的shell(当然你机器上使用的shell 数可能和
这里列出的不同):
$ sort -nr uniq.sorted.shells
18 /sbin/nologin
5 /bin/false
4 /bin/bash
2 /dev/null
1 /sbin/shutdown
1 /sbin/halt
1 /bin/sync
1
结果:
得到一个数字逆序排列的、和系统中帐号相关的shell 列表。
实验1b:练习
设计,然后写下每个练习的解。记住,答案是你执行的命令,而不是输出。每个解应该只有一
句命令,并且至少由一个管道实现。你可能需要翻阅man page。答案在实验最后给出。
1、/usr/bin 目录下有多少文件?输出应该是单个的整数。提示:设计一个命令可以每行列出
一个文件,然后想想如何统计这些行数。
_____________________________________________________
2、对/usr/share/doc/nautilus-1.06/NEWS 作一次拼写检查。
_____________________________________________________
3、练习2 得到多少不重复的(unique)的单词?
_____________________________________________________
4、练习2 中,输出重复出现超过一次的单词列表。
_____________________________________________________
实验2:用grep 作字符处理
任务:
1、使用grep 显示你home 目录下的passwd 文件(/etc/passwd的拷贝)中,以'g'开头的帐户
:
$ grep ^g passwd
2、显示所有的使用bash shell的帐户:
$ grep bash$ passwd
3、显示所有不使用bash shell 的帐户
$ grep -v bash$ passwd
4、为了演示diff 的使用,建立一个修改过的passwd 拷贝。使用grep 删除任何含有'N'或者
'P'的行:
$ grep -v [NP] passwd > modified.passwd
5、最后,用tr 转换所有的大写字母为小写字母:
$ tr "A-Z" "a-z" < modified.passwd > modified2.passwd
6、使用cat 查看你原先的passwd 和modified2.passwd。如果不仔细看的话,区别难以找到。
使用diff 生成两个文件之间差异的列表,用统一格式:
$ diff -U 0 modified2.passwd passwd
实验3:正则表达式和字符操作
设计,然后写下每个练习的解。记住,答案是你执行的命令,而不是输出。你可能需要翻阅
man page。答案在实验最后给出。
任务:
1、试着用grep 将/usr/share/dict/words 中和查找项相符的项输出。例如,显示所有包含
fish 的项:
$ grep fish /usr/share/dict/words
仔细比较上面和下面的输出,并找出grep 的-i 开关的用处:
$ grep -i fish /usr/share/dict/words
2、使用grep 的man page,构造一个命令可以每行含有在words 文件中找到的fish 项的输出
,且每行前后都空两行(提供其他的内容),然后执行它。
________________________________________________
3、使用grep 的man page,构造一个命令可以输出fish 项在words 文件中找到的个数,然后
执行它。
________________________________________________
4、使用grep 的man page,构造一个命令可以将fish 项在words 中匹配的行,包括它的行号
。在哪行找到了starfish?
________________________________________________
5、列出/usr/share/dict/words 文件中含有t、一个元音字母、接着是sh的单词。
________________________________________________
6、为/usr/share/dict/words 构造一个匹配abominable, abominate, anomie 和 atomize(
但不匹配其他)的正则表达式。
________________________________________________
7、在/usr/share/dict/words 中有多少词包括t,一个元音字母,以sh 结尾的单词?构造命
令并执行,它应只输出个数。
________________________________________________
8、列出/usr/share/dict/words 中只含16个字母的单词。
________________________________________________
9、/usr/share/doc 是个有用的信息源。我们在后面几个任务中将使用这个目录中的文件。
列出含有词'expansion'的普通文件的文件名
___________________________________
10、显示'Linux'这个词在/usr/share/doc/bash-2.05a目录下的文件中的出现频率。但是不要
输出含0次的文件。提示:先统计所有文件的个数,然后考虑你如何禁止与某一项相匹配的行
的输出。
________________________________________________
11、列出在/usr/share/doc 下所有含有'Havoc' 的文件的文件名
________________________________________________
12、你可以使grep 递归查找目录下的文件:
grep -R --include=<file_globbing_pattern> <search_string> <file_name(s)>
使用这种技术,将/usr/share/doc 下所有含有'ethernet' 的文件列出。
________________________________________________
13、只显示那些文件的文件名
________________________________________________
14、特殊的挑战性任务:
设计一个命令,可以显示在练习13显示的文件中含有'authentication'的文件。记住
backquotes(``)可以先计算内表达式,然后将其替换命令行中的相应内容。
________________________________________________
15、使用类似的技术查找/usr/share/doc 下含有'regular expression',但不含'perl'的文
件(均为大小写敏感)
________________________________________________
16、列出/usr/share/doc 下所有含有美国州名和9位邮政编码的(格式:XX NNNNN-NNNN)、
且文件名以".txt"结尾的文件。
________________________________________________
实验4:探索管道的应用
任务:
1、在实验1a中,你使用了多种字符处理程序,在4步骤内建立了排序的shell 列表。在本实验
中你将完成同样的任务,但是只用一步。
为了建立排序的shell 列表,组合实验1a中步骤3到6的命令。和上次实验不同,这次不需要任
何临时文件。因为整个操作多次将输出管道定向到另一个命令中。
$ cut -d: -f7 passwd | sort | uniq -c | sort -nr
18 /sbin/nologin
5 /bin/false
4 /bin/bash
2 /dev/null
1 /sbin/shutdown
1 /sbin/halt
1 /bin/sync
1
2、要查看所有以root 运行,按字母表排序的进程列表,使用ps 输出带用户名的进程列表,
然后管道定向到grep 以产生只有root 所拥有的进程列表。^告诉grep 只在每行的行首查找
root 字串
$ ps auxw | grep ^root
3、假设你需要将这些数据传给一个只需要进程名的script。为了产生该列表,使用tr 和cut
的组合。首先,用tr 将空格压缩成cut 能理解的分界符(这里是a%)。然后,使用cut 只显
示进程名(tr 输出的第11列)
$ ps auxw | grep ^root | tr -s [:blank:] [a%] | cut -d% -f11
4、现在我们有了属于root 进程的列表。但是我们让cut 只显示第11列,这样我们失去了该进
程的命令行参数。在第二步中,我们知道最后一个进程syslogd带有参数-m 0,但是在第三步
我们只看到syslogd。将-f11 改为-f11-,使得cut 将11列到最后的列全部裁减输出。
$ ps auxw | grep ^root | tr -s [:blank:] [a%] | cut -d% -f11-
5、我们几乎已经达到了需要的输出。记住我们使用了tr 转换空格为分界符a%,以使cut 可用
。现在我们需要再次用tr 将%back 转换成空格。
$ ps auxw | grep ^root | tr -s [:blank:] [a%] | cut -d% -f11- | tr [%back] "[]"
6、就像你前面看到的,在使用命令行工具时,管道是一种非常有用的工具。前面这些步骤完
成了我们的工作,但是在花费很多时间折腾输出前,请务必确认该程序是否有可能格式化成你
所需要的格式。ps,特别地,能输出几乎你能想象的格式。请注意看下面命令的开关是如何完
成我们需要的输出的:(哎!)
$ ps -u root -o args
结果:
使用管道的命令的组合,输出root 拥有的系统进程列表。
实验3答案:
1、grep -B2 -A2 "fish" /usr/share/dict/words
4、grep -c "fish" /usr/share/dict/words
5、 grep "t[aeiou]sh" /usr/share/dict/words
6、 "^a.om.*e$"
7、 grep -c "t[aeiou]sh$" /usr/share/dict/words
8、 grep -c "................" /usr/share/dict/words
(为什么不是 grep -c ".\{16\}" /usr/share/dict/words ?)
9、 grep -l expansion /usr/share/doc/bash-2.05a/*
10、 grep -c "Linux" /usr/share/doc/bash-2.05a/* | grep -v ":0"
11、grep -R "Havoc" /usr/share/doc
12、 grep -R --include="*txt" ethernet /usr/share/doc
13、 grep -lR --include="*txt" ethernet /usr/share/doc
14、 grep -i autentication `grep -lR --include="*txt" ethernet /usr/share/doc`
15、 grep -ivl perl `grep -Rli --include="*txt" "regular expression"
/usr/share/doc`
16、 grep -R --include="*.txt" \
" *[A-Z][A-Z] *[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]" |
|