习题答案Linux操作系统原理实践教程崔继清华大学出版社.docx
《习题答案Linux操作系统原理实践教程崔继清华大学出版社.docx》由会员分享,可在线阅读,更多相关《习题答案Linux操作系统原理实践教程崔继清华大学出版社.docx(34页珍藏版)》请在冰豆网上搜索。
习题答案Linux操作系统原理实践教程崔继清华大学出版社
第1章
1、在VMwane中安装CentOS7的基本步骤有哪些?
(1)新建虚拟机
(2)虚拟机设置
(3)启动虚拟机
(4)设置安装信息,包括软件选择,安装位置,分区等
(5)完成最后安装
2、安装Linux时可以设置哪些分区?
有哪些分区是必须的?
能够设置的分区可以根据安装系统时提示,主要包括:
/,/boot,swap,/home,/opt等等;其中/(根)分区是必须的。
第2章
1、针对Linux系统启动运行,有哪些运行目标?
每个运行目标的含义是什么?
CentOS从7.0开始使用systemd代替init作为系统启动和服务器守护进程的管理器,负责在系统启动或运行时,激活系统资源,管理服务器进程。
systemd用目标(target)替代了运行级别的概念,提供了更大的灵活性,比如可以继承一个已有的目标,并添加其他服务来创建自己的目标。
CentOS7.0之前的运行级别和systemd目标之间的对应关系如下表所示。
2、Linux有几种关机方法,每种关机操作有何异同?
关闭系统的命令有:
shutdown(最安全的方式),halt,init,telinit,poweroff,reboot,具体含义可以参考帮助手册页。
第3章
more、less、cat、wc命令有什么区别?
这几个命令可用于对文本文件的处理显示,主要区别在:
more命令以分页(一次一屏)显示文本信息;less类似于more,但增加了回滚功能;cat本意是连接文件并在标准输出上输出,也就是将文件一次全部输出;wc用于统计输出文件中的行数、单词数、字节数等。
第4章
(1)发出命令显示行号。
底端命令方式下
:
setnu
(2)保存到文件AboutLinux,并不退出。
底端命令方式下
:
wAboutLinux
(3)删除一句“ItisthiskernelthatformsthebasearoundwhichaLinuxoperatingsystemisdeveloped.”。
在命令方式下,先把光标移到It处,再按d$。
(从当前光标处到行末的所有字符删除)
(4)查找单词“Finland”。
命令方式下输入/Finland,回车后会在第一个Finland处停下来。
(5)把第一段的“Finland”单词后的内容换行,使其变成三段内容。
插入方式下,将光标移到Finland后,按回车键即可。
(vi的换行标志是回车符)
(6)将第二段的内容复制到文档的最后。
命令方式下:
先用yy命令,然后移到文档最后,再按p键。
(7)删除第三段的内容。
命令方式下,光标移到第三段,用dd命令。
(注,这里的段实际上是第3行。
)
(8)恢复被删除的一段内容。
命令方式下,用u命令。
(9)查找所有的“Minix”单词,并全部改为“MINIX”。
底端命令方式下,:
1,$s/Minix/MINIX/g
(10)不保存修改,退出vi。
底端命令方式下,:
q!
(11)使用vi再次打开文件AboutLinux,在第二段后插入“Hebeganhisworkin1991whenhereleasedversion0.02andworkedsteadilyuntil1994whenversion1.0oftheLinuxKernelwasreleased.”。
shell命令提示符下输入:
viAboutLinux(打开保存的文件)
可以使用命令:
:
2快速移到指定的行(这里是第2段)
使用A命令从当前行的最后一个字符开始编辑。
(12)保存并退出vi。
底端命令方式下,:
wq
第5章
【任务1】查看和修改/root/anaconda-ks.cfg文件的权限。
填写下表:
(注,使用符号法修改权限,答案不唯一,这里只给出了一种答案。
)
操作目的
文件所有者
文件所属组
其他用户
参考操作命令
查看anaconda-ks.cfg的权限
rw-
---
---
ls–l/root/anaconda-ks.cfg
使用字符修改法将文件所有者、文件所属组、其他用户均设置为可读、可写、可执行
rwx
rwx
rwx
chmoda=rwx/root/anaconda-ks.cfg
使用字符修改法将文件所属组去掉执行权限、其他用户去掉可写、可执行权限
rwx
rw-
r--
chmodg-x,o-wx/root/anaconda-ks.cfg
使用数字的方式将文件所有者设置为可读、可写、可执行,文件所属组、其他用户均无权限
rwx
---
---
chmod700/root/anaconda-ks.cfg
使用数字的方式将文件所有者设置为可读、可写,文件所属组、其他用户均为可读
rw-
r--
r--
chmod644/root/anaconda-ks.cfg
【任务2】用户和用户组权限设置验证
用户组
用户
文件
group01
user1,user2
/home/user1/a.txt,由用户user1创建。
group02
user3
操作步骤:
1、创建用户组
group01,group02
参考命令:
groupaddgroup01
groupaddgroup02
2、创建用户并将用户加入组中
参考命令:
useradd–ggroup01user1
useradd–ggroup01user2
useradd–ggroup02user3
passwduser1
passwduser2
passwduser3
3、使用帐户user1登录系统,在家目录/home/user1中新建文件a.txt,编辑文件的内容(具体内容自定)。
可以使用vi创建文件a.txt,同时编辑内容。
操作步骤如下:
(1)via.txt进入vi编辑器
(2)按i键进入插入模式,自己编写一段内容。
如下图所示。
(3)保存退出。
4、修改用户家目录/home/user1的权限,增加同组和其它人都可以读和执行权限。
注,修改权限的方式不唯一,可以是字符模式,也可以是数字模式,你可以选择你喜欢的任一种模式。
下同。
5、用帐号user2,user3分别登录,测试文件a.txt是否可读、可写。
结果:
user2可读,不可写;user3可读,不可写。
如图,以user2登录为例:
使用vi编辑器编写文档a.txt时会提示该文件为只读文件。
6、切换到帐户user1,改变文件a.txt权限,使用户user2、user3对文件a.txt有读写权限。
7、
8、用帐号user2,user3分别登录系统,测试文件a.txt是否可读、可写。
user2和user3均对文件a.txt具有可读、可写权限。
如图,以user2登录测试为例。
9、切换到root用户,修改文件a.txt的属主为user2。
第6章
1、使用ls命令查看文件:
/bin/ls、/dev/sda、/dev/tty、/dev/stdin文件,完成表格6-1中的内容。
注:
需要使用ls–l命令查看。
表6-1文件属性信息表
文件标识
访问权限
文件对象
-
rwxr-xr-x
/bin/ls
b
rw-rw----
/dev/sda
c
rw-rw-rw-
/dev/tty
l
rwxrwxrwx
/dev/stdin->/proc/self/fd/0
思考题:
根据文件标识,分别说出这4个文件的类型。
-:
普通文件
b:
磁盘块文件
c:
字符块文件
l:
符号链接
2、使用df命令以便于阅读的方式查看文件系统磁盘空间使用情况,完成表格6-2中的内容。
(可以添加行)
注:
可以使用–h–T选项以显示表中的数据。
表6-2文件系统磁盘空间使用情况表
文件系统
类型
容量
已用
可用
已用%
挂载点
/dev/sda2
xfs
14G
4.4G
9.7G
32%
/
/dev/sda1
xfs
297M
107M
191M
36%
/boot
备注:
这里填写的只是示例,填写内容以实际看见的数据情况为准。
3、使用命令xfs_info或xfs_growfs查看某个xfs文件系统信息,完成表格6-3中内容。
注:
这里以/dev/sda1文件系统为例,使用命令xfs_info/boot可查看文件系统信息。
显示效果如下图所示。
表6-3查看xfs文件系统
挂载点
/boot
inode的大小
512B
AG组数
4个
AG组中块数
19200个
扇区大小
512B
块的大小
4096B
文件系统内总块数
76800
Log的位置
Internal(表示在内部)
Log占用磁盘空间
4K*855=3420K
备注:
上述内容仅供参考,文件系统的大小不一,看到的结果不一。
4、使用命令xfs_admin或xfs_db查看某个xfs文件系统超级块信息,完成表格6-4的内容。
注:
本处以查看/dev/sda2(“/”文件系统)为例。
命令如下:
xfs_admin-f/dev/sda2
xfs_admin>sb0
xfs_admin>print
表6-4查看超级块信息
魔数
0x58465342(即XFSB)
uuid
9f173e78-c60e-44e3-8894-51fadb75c012
块大小
4096B
块的个数
3662080
日志的第一个块
2097156
根结点号
64
AG的个数
4
AG中块的个数
915520
inode大小
512
每个块中包含结点个数
8
已分配inode个数
97664
剩余可用inode个数
159
备注:
上述内容仅供参考,文件系统的大小不一,看到的结果不一。
5、使用命令stat查看文件/bin/ls的inode信息,完成表格6-5中的内容。
表6-5查看文件inode信息
inode号
25186417
文件类型
普通文件
权限
0755/-rwxr-xr-x
磁盘块数
232
链接数
1
文件大小
117672B
6、按下列步骤完成链接文件的操作:
(1)在当前目录下创建文件myfile(提示:
可用touch、vi等完成),文件的内容自定。
(2)为myfile创建硬链接文件hmyfile。
(提示:
用ln命令完成)
(3)为myfile创建符号链接文件smyfile。
(提示:
用ln-s命令完成)
(4)使用stat命令查看文件myfile、hmyfile、smyfile,可以得出什么结论?
回答:
命令:
lnmyfilehmyfile创建硬链接
命令:
ln-smyfilesmyfile创建符号链接
如果使用ls–li命令查看,效果如下:
使用stat命令查看效果如下:
结论:
硬链接是给文件提供了另外一个入口,硬链接的文件只是文件名不同而已,文件的所有属性都相同。
对其中任何一个文件的修改都会导致另外文件的修改。
删除其中一个文件不会对另一个文件造成影响。
符号链接是给文件(源文件)创建另外一个打开路径(链接文件),通过不同的文件名打开相同的文件,两个文件的文件属性包括inode号码不同。
如果删除源文件,将造成链接文件无法使用。
第7章
列举常用的Linux文件与目录操作命令及用法实例,并上机完成目录创建、进入目录、建立文件、显示文件、显示目录、管道操作、输出重定向、文件合并、文件拆分、文件查找等功能(命令)。
略
第8章
【任务1】进程管理的基本命令使用练习
注,本答案中的截图均为示例图,效果显示可能不一致。
1、显示系统中所有进程的全部信息:
输入命令#ps–ef。
2、显示所有终端所有用户有关进程的所有信息:
输入命令#psaux,并记录其输出哪些信息。
3、查看进程树:
#pstree
4、查看进程树同时显示进程号:
#pstree-p
5、动态显示系统当前的进程和状态,每隔5秒的时间刷新一次:
输入命令#top-d5
6、在目录/tmp/test下用vi新建test.txt文件(如果目录/tmp/test不存在,则创建之),然后用kill将其终止。
a)输入命令#vitest.txt。
b)新建一个终端,输入命令#ps–ef查看vi的进程PID。
c)终止该进程,输入命令#kill,如:
kill2305
d)输入命令#ps–ef,查看vi进程是否存在(类似于下图)。
输入命令:
kill1376后,vi进程应该不存在了。
7、查看进程bash当前的优先级值,并将其值下调5。
可以使用ps–l获取bash的PID号,如为1174;然后使用命令renice+51174调整。
【任务2】完成计划任务的设置
1、使用at命令执行一次性计划任务
在当天23点30分将/var/log中的内容打包备份,命名为log1.tar.gz。
at23:
30today
tar–czf/root/log1.tar.gz/var/log
Ctrl+D(存盘退出)
效果如下图所示。
2、使用cron制定周期性计划任务
设置每周5晚23点30分执行日志备份,将/var/log中的内容打包备份,命名为log2.tar.gz。
使用命令:
crontab–e,进入如下画面,填写如下记录,保存退出。
验证效果:
(在指定的时间,指定的/root目录下生成的两个打包压缩文件测试效果图)
第9章
【任务1】阅读理解代码后,利用gcc编译程序。
命令:
gccrwbfile.c-orwbfile
在磁盘的/root目录下,是否有文件“file1.bin”、“file2.bin”产生?
如果有,它们的内容可以直接读取吗?
答:
在/root目录下,会产生“file1.bin”、“file2.bin”两个文件,均为二进制文件,不可以直接读取。
4、修改读写缓存大小,使得一次可以读取256个字节。
再次运行程序,查看运行结果。
(贴图显示)
修改此处的值即可。
【任务2】
①:
pid=fork()
②:
getpid()
③:
getpid()
问题:
为什么程序输出内容中间会出现shell提示符?
原因:
父进程只执行了3次,结束时会出现shell提示符。
此时子进程尚没有结束(需要执行5次),所以子进程继续运行,在父进程结束处出现了子进程的运行提示信息,如图所示。
解决方法:
可以在程序中添加让父进程等待子进程结束的语句。
如下图代码所示:
测试运行结果类似如下图所示:
第10章
【任务1】上机测试程序。
给出程序的功能及运行结果。
功能:
此程序模仿ps程序的执行。
父进程打印控制菜单并接收命令,创建子进程。
子进程处理任务。
此处模拟有两个功能:
命令:
ps–a
命令:
psx
【任务2】
答案:
①:
pid
②:
"/bin/ps","ps","-a",NULL
③:
NULL
【任务3】
#include
#include
#include
#include
#include
intmain()
{
pid_tpid;
intn;
pid_tchild_pid;
intexit_code;
pid=fork();
switch(pid)
{
case-1:
perror("forkfailed!
");
exit(EXIT_FAILURE);
break;
case0:
n=5;
for(;n>0;n--){
printf("childprocessPIDis%d.\n",getpid());sleep
(1);}
exit_code=88;/*此处值是随便写的,没有实际意义,下同。
*/
break;
default:
n=3;
for(;n>0;n--){
printf("parentprocessPIDis%d.\n",getpid());sleep
(1);}
exit_code=66;
}
/*父进程等待子进程完成*/
if(pid!
=0)
{
child_pid=wait(&exit_code);
printf("childhasfinished:
PID=%d\n",child_pid);
if(WIFEXITED(exit_code))
printf("childexitedwithcode%d\n",WEXITSTATUS(exit_code));
else
printf("childterminatedabnormally\n");
}
exit(exit_code);/*子进程终止时会用该函数将返回值带回给父进程*/
}
第11章
1、四个进程A、B、C、D都要读一个共享文件F,系统允许多个进程同时读文件F。
但限制是进程A和进程C不能同时读文件F,进程B和进程D也不能同时读文件F。
为了使这四个进程并发执行时能按系统要求使用文件,现用PV操作进行管理,请回答下面的问题:
(1)应定义的信号量及初值:
(2)在下列的程序中填上适当的P、V操作,以保证它们能正确并发工作:
A()B()C()D()
{{{{
[1];[3];[5];[7];
readF;readF;readF;readF;
[2];[4];[6];[8];
}}}}
解答:
(1)定义二个信号量S1、S2,初值均为1,即:
S1=1,S2=1。
其中进程A和C使用信号量S1,进程B和D使用信号量S2。
(2)从[1]到[8]分别为:
P(S1)V(S1)P(S2)V(S2)P(S1)V(S1)P(S2)V(S2)
第12章
1、分析11.4.2中的程序的功能。
并回答下面几个问题:
(1)使用wait函数的目的是什么?
(2)为什么要使用memset函数?
(3)查看父进程和子进程的ID各是多少?
(提示:
可以使用在后台执行程序,查看进程号)
解析:
(1)等待子进程结束后再继续运行。
(2)memset可以方便的清空一个结构类型的变量或数组。
一般用来初始化,避免原来的数据影响当前运算的结果。
(3)可以通过进程查看器或者PS命令进行查看。
2、分析11.4.3中的程序,说明函数unlink的作用。
解析:
用来删除通信完毕的管道文件,避免产生冗余文件,占用磁盘空间。
第13章
尝试使用发送与接收中的key值不一样或者设为0,看看是怎样的结果。
分析一下原因。
解析:
无法通信,利用IPC对象进行通信的进程必须通过key值获取同一个IPC对象的ID号后方可进行信息的发送和接受,如果不一致会导致无法通信。
如果设置为0,则该IPC对象仅用于私有通信,无法用来与其他外部进程进行通信。
第14章
1、一个信号量集中包含多个信号量结合共享内存如何实现进程间的同步和互斥。
解析:
如果两个进程不仅需要同步,还要保证先后执行顺序,就要用两个信号量(互斥锁)来解决。
如下案例为利用两个信号量进行同步和互斥的过程,可作为参考,然后在此基础上添加通信过程。
#include
#include
#include
#include
#include
#include
#include
#include
#definePROCESS_NR4
voidsigFunc(intsigno)
{
intsemId;
semId=semget(0x555,PROCESS_NR+1,IPC_CREAT|0600);
if(semId>0){
semctl(semId,0,IPC_RMID);
}
exit
(1);
}
voidp_lock(intidx,intsemId);
voidwaitZero(intsemId);
voiddoWork(intidx,intsemId);
intmain(void)
{
intsemId,i;
pid_tpid;
////////////////////////////////
//对应的下标的信号量控制对应的子进程最后一个信号量控制父进程
semId=semget(0x555,PROCESS_NR+1,IPC_CREAT|0600);
if(semId==-1)
{
perror("createsem");
return11;
}
//initsemvalue
unsignedshortvals[PROCESS_NR+1]={0};//对多个信号量值进行初始化
if(semctl(semId,0,SETALL,vals)==-1)
{
perror("initsemval");
semctl(semId,0,IPC_RMID);
return12;
}
////////////////////////////////
for(i=0;i{
pid=fork();
if(pid==-1)return1;
elseif(pid==0)//childprocess
{
doWork(i,semId);//i标识进程的编号
exit(0);
}
}
//
signal(SIGINT,sigFunc);
//parent
structsembufbufs[PROCESS_NR+1]={0};
for(i=0;i{
bufs[i].sem_num=i;
bufs[i].sem_op=1;
}
bufs[PROCESS_NR].sem_num=PROCESS_NR;//父亲的资源
bufs[PROCESS_NR].sem_op=PROCESS_NR;
////////////////////////////////////////
while
(1)
{
waitZero(semId);
printf("========升起栅栏=======\n");
semop(semId,bufs,PROCESS_NR+1);
}
whil