目录
实验一 Linux 系统的安装........................................................ 5
实验二 Linux 基础.................................................................... 4
实验三 编辑器 vi 和编译器 gcc 的使用............................... 5
实验四 进程管理........................................................................................ 4
实验六 进程间通信........................................................................................ 5
实验七 存储器管理........................................................................................ 2
实验八 Linux文件系统...................................................................................... 15
实验一 Linux 安装
日期: 2023年4月7日 报告分:
一、实验目的
了解 Linux 系统,熟悉 Linux 文件和目录。
二、预习报告
1. Linux背景
Linux是一种自由和开放源代码的类Unix操作系统,它最初是由芬兰的林纳斯·托瓦兹(Linus Torvalds)在1991年创建的。Linux的内核是由一些志愿者组成的全球性开发团队共同维护的,它是一个高度可定制的系统,用户可以自由地修改和定制它以适应不同的需求。Linux被广泛应用于服务器、超级计算机、嵌入式系统、移动设备等领域。
Linux 是一类 Unix 计算机操作系统的统称,Linux 操作系统是 UNIX 操作系统的一种克隆系统,现已成为今天世界上使用最多的一种 UNIX 类操作系统。Linux 操作系统
的诞生、发展和成长过程始终依赖着以下五个重要支柱:UNIX 操作系统、MINIX 操作系统、GNU 计划、POSIX 标准和 Internet 网络。
主流的 Linux 发行版: Ubuntu, Debian GNU/Linux,Fedora,Gentoo ,
MandrivaLinux ,PCLinuxOS,Slackware Linux ,openSUSE,ArchLinux,
Puppylinux,Mint, CentOS,Red Hat 等。
1.1 Red Hat
Red Hat 是全球最大的开源技术厂家,其产品 Red Hat也是全世界应用最广泛的 Linux。但是自2004 年 4 月 30 日,Red Hat 公司正式停止对Red Hat 9.0 版本的支持,Red Hat 公司不再开发桌面版的 Linux 发行包,而将全部力量集中在服务器版的开发上,也就是 Red Hat Enterprise Linux 版。原本的桌面版
Red Hat Linux 发行包则与来自民间的 Fedora 计划合并,成为 Fedora Core 发
行版本。
1.2 Fedora Linux
当 Red Hat Linux 停止发行后, Fedora 社区便集成到 Red Hat 赞助的 Fedora Project,目标是开发出由社区支持的操作系统。Fedora 可以说是 Redhat 桌面版本的延续,只不过是与开源社区合作。(免费)
1.3 Ubuntu
Ubuntu 是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖
鲁语或豪萨语的“ubuntu”一词(译为吾帮托或乌班图)。Ubuntu 是一个社区开发的基于Debian GNU/Linux的操作系统,适合笔记本、桌面计算机和服务器使用。(免费升级到最新版)
2. Linux安装
2.1 安装步骤
1. 下载并安装虚拟机软件,如VMware Workstation或VirtualBox。
2. 下载Linux操作系统的ISO镜像文件,如Ubuntu(下载地址https://cn.ubuntu.com/download/desktop)、CentOS等。
3. 打开虚拟机软件,创建一个新的虚拟机。
4. 在创建虚拟机时,选择刚刚下载的Linux ISO文件作为虚拟机的操作系统。
5. 设置虚拟机的硬件参数,如内存(至少2G,大一点运行速度更快)、硬盘容量、网络等。
6. 启动虚拟机,安装Linux操作系统。
7. 在安装过程中,按照提示完成各项设置,如选择安装位置、设置用户名和密码等。
8. 安装完成后,重启虚拟机,进入Linux操作系统。
9. 在Linux操作系统中,可以使用命令行或图形界面进行各种操作。
三、实验内容与结果记录
1. 实验内容
Linux 的安装方式可以有以下几种选择:
(1)光盘驱动器安装,将 Linux 系统的映像刻录成光盘由光盘引导安装。
(2)硬盘驱动器安装,将 Linux 系统下载到硬盘驱动器中,直接安装。
(3)网络安装方法,无须下载,直接从网络服务器中直接安装。
实验要求将自己的计算机配置成 Linux 与 Windows 两个操作系统并存的系统。启动时可以由我们自主选择是进入 Linux 还是进入 Windows。或者先安装虚拟机,再将Linux 安装在虚拟机上。常用的虚拟机软件有 VMware Workstation,Virtual Box等。
2.实验步骤
按照预习中的安装步骤完成了Linux以及虚拟机的安装。
3.实验结果
启动Linux效果如下:
四、遇到的问题及解决方法
本次安装实验过程中,由于开始下载虚拟机时没有从官网下载,而是从网上某个博客获取的,导致出现了安装失败的问题,后来重新从官网下载就成功安装了。所以以后尽量在官网下载,别的地方可能不正规或者捆绑软件,会浪费许多时间。
在进行这次操作系统实验的过程中,我们学到了 Linux 系统的安装步骤及操作系统运行的相关知识,也在实际操作中熟悉了Linux的一些基本命令和配置文件。
实验二 linux基础
日期: 2023年4月12日 报告分:
一、实验目的
了解Linux系统,熟悉Linux文件和目录。
二、预习报告
2.1 Linux文件系统结构
2.1.1 Linux目录结构
Linux 文件系统是树状结构的,系统中每个分区都是一个文件系统,都有自
己的目录层次。Linux 会将这些分属不同分区的、单独的文件系统按照树状的方
式形成一个系统的总目录层次结构。在 Linux 系统中,无论操作系统管理几个磁盘分区,目录树都只有一个。Linux 使用标准的目录结构,在安装的时候,安装程序就已经为用户创建了文件系统和完整而固定的目录结构,并指定了每个目录的作用和其中的文件类型。
2.1.2 重要目录
1. /bin:存放可执行二进制文件的目录,如常用的命令 ls、tar、mv、cat等。
2. /boot:放置 linux 系统启动时用到的一些文件。
3. /dev:存放 linux 系统下的设备文件。
4. /etc:系统配置文件存放的目录。
5. /home:为用户设置的目录,如用户 user 的主目录就是/home/user,也可
以用~user 表示。
6. /lib:标准程序设计库,又叫动态链接库,在 Linux 执行或编译内核时均会
用到,是系统使用的函数库的目录。
7. /lost+fount:系统异常产生错误时,会将一些遗失的片段放置于此目录下。
8. /proc:此目录的数据都在内存中,如系统核心,外部设备,网络状态,
由于数据都存放于内存中,所以不占用磁盘空间。
9./root:系统管理员 root 的家目录,系统第一个启动的分区为/,所以最好
将/root 和/放置在一个分区下。
10. /sbin: /usr/sbin: /usr/local/sbin:放置系统管理员使用的可执行命令,
如 fdisk、shutdown、mount 等。
11./tmp:一般用户或正在执行的程序临时存放文件的目录,任何人都可以
访问,重要数据不可放置在此目录下。
12. /usr:应用程序存放目录,/usr/bin 存放应用程序,/usr/share 存放共享数据。
2.1.3 Linux常见命令
(1) ls 显示目录内容
-a 列出目录下的所有文件,包括以 . 开头的隐含文件。
-d 将目录象文件一样显示,而不是显示其下的文件。
-i 输出文件的 i 节点的索引信息。
-k 以 k 字节的形式表示文件的大小。
-r 对目录反向排序。
-s 在每个文件名后输出该文件的大小。
-R 递归地显示指定目录的各个子目录中的文件。
-l 以长格式列出文件的详细信息。
(2)cat显示文件
cat 命令的功能是显示文件内容,也可用于文件的连接。此命令常用来快速
浏览文件。如果没有指定文件或连接符号(-),就从标准输入读取。
-b 计算所有非空输出行,开始为 1。
-n 计算所有输出行,开始为 1。
-s 将相连的多个空行用单一空行代替。
-E 在每行末尾显示“$”符号。
示例:
- 显示文本文件 2.txt 的内容,并在每行显示行号:
- 键盘输入“$cat >myfile.txt”并按“Enter”键后,光标回到下一行的
行首,在此等待用户从键盘输入正文。正文输入完毕,同时按下 Ctrl+D,存盘并退出:按 Delete 键,放弃并退出。
就会新建一个myfile.txt文本文件,cat -b myfile.txt进行查看
(3)chmod 改变文件或目录的访问权限
chomod 命令用来重新设定不同的访问权限,用户用它控制文件或目录的访
问权限。该命令有两种方法,一种是包含字母和操作符表达式的文字设定法,另
一种是包含数字的数字设定法。
- 文字设定法
chmod o+w hello1.c为文件 hello1.c 的其他用户增加写权限;
chmod g=x hello1.c 给 hello1.c 的同组用户赋予执行权限,同时去除读、写权限;
chmod go-rwx hello1.c取消其他用户对目录 hello1.c 的读写和执行权限;
- 数字设定法
chmod 751 file2将文件 file2 设置为 rwxr-x--x 权限
chmod 777 file3将文件 file3 设置成对所有用户拥有读、写和执行权限
(4)cp 文件或目录的复制
-f:强行覆盖已存在的目标文件。
-i:在强行覆盖已存在的目标文件时给出提示。
-R:整个目录复制。
示例 :
- 将当前目录下的文件 myfile.txt 复制成 myfile2.txt
cp myfile.txt myfile2.txt
- 将/home/bi0x/Desktop/ 目录下的文件 myfile.txt 复制到/home/bi0x/Desktop/dzj 目录中,并取名 file1.txt,若/home/ bi0x/Desktop/dzj 目录中已经存在 file.txt,则覆盖该文件前询问用户。
cp /home/bi0x/Desktop/myfile.txt /home/bi0x/Desktop/dzj/file1.txt
补充:桌面目录:/home/用户名/Desktop(注意D大写)
(5)mv( 文件或目录更名或将文件由一个目录移到另一个目录中)
-i 询问方式操作。如果 mv 操作将导致对已存在的目标文件被覆盖,此时系统会询问是否重写,并要求用户回答 y 或 n,这样可以避免错误地覆盖文件。
-f 禁止询问操作。在 mv 操作要覆盖某个已有的目标文件时不给予任何提示,指定选项后,-i 选项将不再起作用。
示例:
- 将当前目录下的文件 file1 更名为 file2
mv file1 file2
- 将当前目录下的文件 file 移到上一层目录
mv file ..
(6)rm(删除文件或目录)
-f 忽略不存在的文件,不给出提示
-r 指示 rm 将参数中列出的全部目录和子目录均递归地删除。如果没有使用-r 选项,则 rm 不会删除目录。
-i 进行交互式删除。使用 rm 命令要特别小心。因为一旦文件删除,它是不能被恢复的。为防止这种情况的发生,可以使用 i 选项来逐个确认要删除的文件。
示例:
- 删除文件file.txt(注意带上文件后缀)
rm file.txt
(7)mkdir(创建目录)
-m 对新建目录设置存取权限,也可以用 chomod 命令修改该权限
-p 可以使一个路径名称。此时若路径重点某些目录尚不存在,加上此选项
后,系统将自动建立那些尚不存在的目录,即一次可以建立多个目录。
示例:
- 在当前目录下新建一个newdir目录
(8)rmdir(删除空目录)
示例:
- rmdir newdir删除当前目录下名为newdir的空目录
(9)cd(改变工作目录)
cd ../返回上一级目录
cd /根目录
cd /home/bi0x/Desktop 到桌面目录
(10)pwd(显示出当前工作目录的绝对路径)
2.1.4 Linux的其它命令
(1)date(显示和设置系统日期和时间)
例 以标准格式显示当前系统日期时间
$date
(2)echo(显示字符串)
命令格式
echo [-n] 字符串
说明:选项 n 表示输出文字后不换行;字符串可以加引号,也可以不加引号。
用 echo 命令输出加引号的字符串时,将字符串原样输出;用 echo 命令输出不加 引号的字符串时,将字符串的各个单词作为字符串输出,各字符串之间用一个空格分隔。
例 显示字符串“Hello, everybody!”
$echo “Hello, everybody!”
(3).cal(显示日历)
命令格式
cal [选项] [月份] [年]
选项含义
-j 显示出给定月份中的每一天是一年中的第几天(从 1 月 1 日作为第一天
算起)。
-y 显示出整年的日历。
例 显示出当前月份的月历 $cal
显示年历 $cal –y
(4)clear(清屏)
(5) kill(向指定进程发送信号)
(6)ps(进程查看命令)
例查看属于自己的进程的详细信息
$ps -u
以长格式查看属于自己的进程的详细信息
$ps -l
查看其他用户进程的详细信息
$ps –al
查看后台运行的进程
$ps -aux
(7)who(查看当前在线用户的情况)
命令格式
who
说明:该命令主要用于查看当前线上用户情况,系统管理员可以用此命令来
24 监视每个登录用户的情况。
例 查看当前登录到系统的用户信息
$who
(8)reboot 命令
reboot 命令的功能是重新启动系统,用法是: $reboot
(9) passwd(修改用户口令)
(10)su(改变用户权限)
命令格式
su {使用者账号}
说明:它可以让一个普通用户拥有超级用户或其他用户的权限,也可以让超
级用户以普通用户的身份做一些事情。普通用户使用这个命令时必须有超级用户或其他用户的口令。如果要离开当前用户的身份,可以输入命令 exit。
三、实验内容与结果记录
a.用who 命令显示当前正在你的Linux系统中使用的用户名字:
- 有多少用户正在使用你的Linux系统?给出显示的结果
- 哪个用户登录的时间最长?给出该用户登录的时间和日期。
b.使用下面的命令显示有关你计算机系统信息:uname(显示操作系统的名称),uname –n(显示系统域名),uname –p(显示系统的CPU名称)
- 你的操作系统名字是什么?
- 你计算机系统的域名是什么?
- 你计算机系统的CPU名字是什么?
c.使用passwd命令修改你用whoami命令找到用户名的登录密码。然后使用who -a命令来看看你的用户名和同一系统其他用户的列表。
d.在shell提示符后,输入echo $PS1并按回车键,系统怎样回答?
e.在shell提示符后,输入PS1=%并按回车键,显示屏有什么变化?
f.在shell提示符后,输入set 并按回车键,系统显示环境变量。给出你系统中的环境变量和它的值。
g.本实验用到的命令还有:date、cal、pwd、write、uptime、man等。
1. 登录你的Linux系统。
2. 用命令date显示当前的时间,给出显示的结果。
3. 用cal命令显示下列年份的日历:4、52、1752、1952、2005、2006
a) 给出你显示以上年份年历的命令
b) 1752年有几天,为什么?提示:在因特网上查找答案
回答:1752年有355天,因为当年9月份缩短了11天,从9月3日直接跳到了9月14日,这是由于当时英国采用了新的历法格里高利历。
- 用pwd显示你的主目录(home directory)名字,给出pwd显示的结果。
- 使用alias 命令显示系统中的命令的别名,给出显示的结果。
- 使用uptime 命令判断系统已启动运行的时间和当前系统中有多少登录用户,给出显示的结果。
7. 通过因特网或Linux的man命令得到下面的shell命令、系统调用和库函数功能描述及每个命令使用例子:
Command | Short Description | Example Use |
touch | 创建文件 | touch a.c |
cp | 复制文件 | cp a.c b.c |
mv | 移动文件 | mv b.c ~ |
rm | 删除文件 | rm a.c |
mkdir | 创建文件夹 | mkdir d |
rmdir | 删除文件夹 | rmdir d |
ls | 列举所有文件 | ls |
cd | 改变工作目录 | cd d |
pwd | 获取路径 | pwd |
open | 帮助启动程序 | open -h |
read | 从标准输入读取数值 | read testfile |
write | 传讯息给其他使用者 | write user |
close | 关闭一个已经打开的文件 | close testfile |
pipe | 前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin) | ls -al /etc | less |
socket | 一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭), 是一组接口 | |
mkfifo | 创建FIFO(命名管道) | mkfifo test |
system | 通过调用/bin/sh -c [command]来执行参数command指定的shell命令 | system() |
printf | 打印文本 | printf abc |
四、遇到的问题及解决方法
对于本次实验,我主要学习了Linux系统的基本命令和操作,对于一些常用的命令如who、uname、passwd、echo、set、date、cal、pwd、write、uptime、man等有了更深入的了解。
在实验过程中,我遇到了一些难题,如在使用cal命令时,不知道如何显示指定年份的日历,经过查找资料,我发现可以使用“cal 年份”来显示指定年份的日历。另外,在使用alias命令时,我不太清楚如何查看系统中命令的别名,后来发现可以直接输入alias命令来查看系统中已经存在的命令别名。
通过本次实验,我更加熟悉了Linux系统的基本命令和操作,对于日常使用Linux系统有了更深入的了解,也更加熟练地使用一些常用的命令。同时,我也认识到在遇到问题时,可以通过查找资料和询问他人来解决问题,提高自己的解决问题的能力。
实验三 编辑器 vi 和编译器 gcc 的使用
日期: 2023年4月20日 报告分:
一、实验目的
掌握编辑器 vi 的基本操作,能够用 vi 来编辑 C 语言源程序;学会 indent 的用法;掌握用 gcc 来做一些简单的编译。
二、预习报告
2.1 vi文书编辑器
vi(visual interface) 是 Unix 世界里极为普遍的全屏幕文书编辑器,vi有三种工作方式,输入模式、命令模式和末行方式。输入模式就是编辑文件(i指令进入编辑);命令模式就是保存、离开等操作指令,用户进入vi就进入命令模式;末行方式也称ex模式,在命令方式中输入冒号:,就进入末行模式,(如esc+”:wq”表示退出并保存)。
一些常用的 vi 命令:
i:在当前光标位置插入文本。
x:删除光标所在位置的字符。
:wq:保存文件并退出 vi 编辑器。
:q!:不保存文件并强制退出 vi 编辑器。
:set nu:显示行号。
yy:复制当前行。
p:粘贴复制的内容。
/word:在文件中查找指定的单词。
:%s/old/new/g:将文件中的所有 old 替换为 new。
通过网上资料查询了解到,vim是vi的增强版,它在vi的基础上增加了很多新特性和功能。vim的编辑速度比vi更快,支持多级撤销和重做、语法高亮、多窗口编辑、插件扩展等。此外,vim还支持多种操作模式,包括命令模式、插入模式、可视模式等,使得编辑更加高效和方便。vi使用于文本编辑,但是vim更适用于coding。
2.2 indent 实用程序
indent 实用程序是 Linux 里包含的另一个编程实用工具。这个工具简单的说就为你的代码产生美观的缩进的格式。此外,在进行美化的过程中还有检查代码的作用。使用时需要先下载: sudo apt install indent。
indent -kr -i8 -ts8 file.c:将 file.c 文件按照 K&R 风格格式化,并使用 8 个空格作为缩进。
indent -linux -i4 -ts4 file.c:将 file.c 文件按照 Linux 风格格式化,并使用 4 个空格作为缩进。
indent -st -br -ce -i4 -ts4 file.c:将 file.c 文件按照 Stroustrup 风格格式化,并使用 4 个空格作为缩进。
示例:
indent first.c执行后
2.3 Linux 的编译器 gcc
Linux 系统上运行的 GNU C编译器(GCC)是一个全功能的ANSIC兼容编译器。虽然GCC 没有继承的开发环境,但堪称是目前效率很高的 C/C++编译器。gcc 是一种流行的编译器,可用于编译多种编程语言,包括 C 语言。使用 gcc 编译器,我们可以将 C 语言源代码编译成可执行文件,然后在终端中运行这个文件。
一些常用的 gcc 命令:
gcc -o output file.c:将 file.c 文件编译成可执行文件 output。
gcc -Wall -o output file.c:将 file.c 文件编译成可执行文件 output,并输出警告信息。
gcc -g -o output file.c:将 file.c 文件编译成可执行文件 output,并添加调试信息。
gcc -c file.c:将 file.c 文件编译成目标文件 file.o。
运行程序示例:
编译C程序命令:gcc first.c -o first
运行C程序:./first
三、实验内容与结果记录
1.编写C语言程序 fork.c:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(void) {
pid_t pid;
printf("Process Creation Study\n");
pid = fork(); //创建一个线程 fork函数调用成功,返回两次
1.返回值为0代表子进程
2.返回值为非负数,代表父进程
3.调用失败返回-1
if (pid < 0) {
perror("Process creation failed\n");
exit(1);
} else if (pid == 0) { //子进程
printf("Child process is running, CurPid is %d, ParentPid is %d\n", getpid(), getppid());// 在子进程中使用getpid()获取子进程id,getppid()获取父进程id.
exit(0);
} else { //非负数代表父进程
printf("Parent process is running, ChildPid is %d, ParentPid is %d\n", pid, getpid());//
在父进程中使用getpid()获取父进程id,pid得到子进程id.
wait(NULL);
exit(0);
}}
2.使用vim编辑器新建c文件fork.c
3.编写代码,使用:wq命令保存并退出
4.安装indent
5.使用indent fork.c整理代码
6.查看格式整理后的代码
7.输入 gcc -o fork fork.c 命令,将 C 语言源代码编译成可执行文件
8.输入 ./fork 命令,运行编译后的可执行文件
注意:运行编译后的可执行文件命令:./文件名,中间没有空格,否则是目录!!
四、遇到的问题及解决方法
刚开始运行编译后的可执行文件的命令:./文件名时中间加了空格,提示是一个目录,后来查资料发现是多了一个空格。
通过本次实验,我学会了如何使用 vi 编辑器和 gcc 编译器进行 C 语言编程,但是相比vi,vim编辑器具有更多的操作模式,使得编程更加方便快捷,因此更适用于编程。
实验四 进程管理
日期: 2023年4月26日 报告分:
一、实验目的
通过实际上机调试和运行程序了解 Linux 系统中的进程基本编程:创建和终止,了解父进程和子进程的概念。
二、预习报告
在Linux系统中,进程被认为是具有一定功能的程序关于一个数据集合的一次运行活动,是处于活动状态的计算机程序。进程在运行态、就绪态、等待态、stopped和zombie这几种状态之间相互转化,但对用户是透明的。每个进程运行在各自的虚拟地址空间中,通过一定的通讯机制,它们之间才能发生联系。新的进程只能由已经存在的父进程调用fork函数进行创建。
fork函数是一个单调用双返回的函数,会给父进程返回子进程的pid,会给子进程返回0,如果创建不成功就会给父进程返回-1。调用fork函数后,子进程和父进程都是从fork函数后面的语句开始执行。每个进程可以有多个子进程,而每个进程至多有一个父进程,利用getppid()函数可以得到父进程的进程标识号。这个可以很简单地区分父进程和子进程。一般父进程和子进程享有同等执行权,交替执行。
如果 Linux 系统中某个进程崩溃,不会影响到其它的进程。每个进程运行在各自的虚拟地址空间中,通过一定的通讯机制,它们之间才能发生联系。
创建一个新进程的唯一方法是由某个已经存在的进程调用 fork 函数(或vfork 函数),被创建的新进程是子进程,已经存在的进程是父进程。
函数 fork()是一个单调用双返回的函数。
没有函数调用可以用来将子进程的进程标识号返回给父进程的;而每个进程至多有一个父进程,利用 getppid()函数可以得到父进程的进程标识号。getuid()获取当前进程用户的id号,getpid()获取执行目前进程的组识别码。
子进程是父进程的一个拷贝。具体地说,子进程从父进程那里得到了数据段和堆栈段的拷贝,这些需要分配新的内存,而不是与父进程共享内存。
三、实验内容与结果记录
(1)lab4a:
结果分析:
先执行了父进程,再执行子进程。
此程序通过调用fork()函数创建了一个子进程,子进程复制了父进程的所有变量和状态,并从fork()函数返回的值判断自己是子进程还是父进程。在父进程中,fork()函数返回的值是子进程的pid,在子进程中,fork()函数返回的值是0。根据这个返回值的不同,父进程和子进程分别输出了不同的信息。
其中,getpid()函数可以获取当前进程的pid,getppid()函数可以获取当前进程的父进程的pid。
父进程调用fork函数之后继续运行直到程序结束,子进程运行到后面的时候由于父进程已经结束了,所以它就成为了孤儿进程。
执行顺序怎么确定的?
fork 之后是父进程先执行还是子进程先执行是不确定的,这取决于内核所使用的算法。
(2)lab4b
结果分析:
① fork 之后是父进程先执行还是子进程先执行是不确定的,这取决于内核所使用的算法。由运行结果可知内核算法是父进程优先的。
② 结果显示父进程和子进程是交替执行的,在父进程中,将msg指向了"Parent process is running"字符串,k赋值为5;在子进程中,将msg指向了"Child process is running"字符串,k赋值为3,所以父进程运行的时间比子进程更长一点。操作系统一般让所有的进程都享有同等执行权,除非某个进程的优先级比其它的高。
(3)lab4c
结果分析:
exec程序先运行,输出Exec example!;然后运行fork函数产生子进程,这时候父进程继续运行到switch函数,输出Parent process is running;然后开始wait,这时候子进程在运行,输出Child process is running;然后是自己的pid和父进程的pid,还有uid和gid,最后调用了进程映像,也就是processimage函数,在processimage函数中再次输出了pid和父进程的pid,还有uid和gid,发现和之前的没有变化,说明子进程和子进程映像用的是同一个pid,也就是子进程映像把原来的程序给覆盖了。
(4)lab4d
先输出"Study how to get exit code",然后创建一个子进程,子进程输出"Child process is running",然后暂停5秒,期间可以查看父进程状态,最后子进程退出。父进程等待子进程结束,输出"Child process has exited, pid = xxx",并根据子进程的退出状态输出"Child exited with code xx"。
程序中父进程等待子进程的方式是调用wait函数,具体实现如下:
- 父进程调用fork函数创建子进程,根据fork函数的返回值判断当前进程是父进程还是子进程。
- 父进程中,如果fork函数返回的是子进程的PID,则进入switch语句中的default分支,设置exit_code为0,然后执行以下代码:
(1) 调用wait函数等待子进程结束,wait函数的参数是一个指向整型变量的指针,用于保存子进程的退出状态。
(2) wait函数返回子进程的PID,父进程根据子进程的退出状态(返回的stat_val值)判断子进程是正常退出还是异常退出,输出相应的信息。
- 子进程中,根据fork函数的返回值判断当前进程是子进程,进入switch语句中的case 0分支,设置msg为"Child process is running"、k为5、exit_code为37,然后执行以下代码:
(1) 子进程暂停5秒,期间可以查看父进程状态。
(2) 子进程执行完暂停操作后,调用exit函数退出,退出码为37。
- 程序最后调用exit函数退出,退出码为exit_code。
四、遇到的问题及解决
问题1:头文件的缺少以及误用会导致报错
解决:通过搜索相应的资料,学会了很多函数、变量声明所需要的头文件,例如在代码中调用exit等系统函数需要加上头文件`stdlib.h`。
通过本次实验,我深入了解了进程的创建、执行、等待和退出等过程,并掌握了进程管理的基本操作。通过实验,我学会了如何编写进程管理程序,还加深了对操作系统原理的理解。
实验五 进程和线程同步
一、实验目的
加深对进程概念的理解,认识并发执行的实质,分析进程征用资源的现象,学习进程、线程互斥的方法。
二、预习报告
本次预习主要学习了Linux下的多线程编程,包括线程的概念、线程的创建和线程私有的数据信息等。线程是计算机中独立运行的最小单位,可以把线程看成操作系统分配CPU的最小单位,各个线程是交替执行的。
虽然线程在进程内部共享地址空间、打开的文件描述符等资源,但是也有线程号、寄存器是私有的信息。每个线程都有一个唯一的线程号与其对应。
线程创建函数pthread_create。进程和线程的创建不同,子进程是通过拷贝父进程的地址空间来实现的;而线程与进程内的线程共享程序代码,一段代码可以同时被多个线程执行。
在多线程编程中,需要注意线程之间的同步和互斥,以避免出现数据竞争的情况。常用的同步和互斥机制包括互斥锁、条件变量和信号量等,可以通过pthread库中提供的相关函数来实现。在编写多线程应用程序时,需要使用头文件pthread.h,链接时需要使用库libpthread.a。
总之,多线程编程是一种高效的编程方式,可以提高程序的并发性和响应速度。但是,在编写多线程应用程序时,需要注意线程之间的同步和互斥,以避免出现数据竞争的情况,同时需要充分利用操作系统提供的多线程编程接口和相关函数库,以提高程序的稳定性和可靠性。
三、实验内容与结果记录
1.createthread.c
第一次运行
修改后运行:
创建一个新线程并输出了线程ID。
注:因为pthread_t(进程唯一标识符)是无符号长整型,需要修改输出格式格式为:%ld。如果不修改的话输出的线程ID可能是负数,因为子线程ID超出了int型。
1.主线程使用pthread_create函数创建了一个新线程并输出线程ID。但是并没有输出“this is a new thread, thread ID=%ld ”,即新线程里面的语句?2.因为如果不在主线程退出之前让其休眠一段时间,就会导致子线程还未打印“已创建”语句时,子线程已经跟随主线程结束。因此,也看不到子线程已创建的语句。
3.程序首先打印出主线程的ID,然后打印新创建线程的ID。
2.oncerun.c
从结果中可以看出:
1.该实例中创建两个线程,分别通过pthread_once调用同一个函数run,结果被调用的函数只在线程2中被执行了一次。说明pthread_once函数将函数调用执行次数限制为一次。
2.函数会在哪个线程中执行是不定的,但是始终只能执行一次。
3.condition.c
主函数初始化了一个互斥锁和一个条件变量,并创建了两个线程。
两个线程会抢占资源,其中一个线程检测到条件变量为真时就进行加锁,并将条件变量设置为假,运行结束后解锁。同时主函数不断将条件变量再设置为真。
thread1由于sleep了4s,而thread2只sleep 1s,所以thread2的运行次数大致是thread1的4倍。两个线程会一直交替执行下去。
四、编程作业
4. 编写一个多线程程序:要求主线程创建3个子线程,3个子线程在执行时
都修改一个它们的共享变量,观察共享变量的值,看看可以得出什么结论。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int sum = 100;
void *thread1(void *arg) {
sum += 10;
printf("thread1 is running, shared_variable = %d\n", sum);
return NULL;
}
void *thread2(void *arg) {
sum += 5;
printf("thread2 is running, shared_variable = %d\n", sum);
return NULL;
}
void *thread3(void *arg) {
sum += 1;
printf("thread3 is running, shared_variable = %d\n", sum);
return NULL;
}
int main(void) {
printf("init shared_variable = %d\n", sum);
pthread_t s1, s2, s3;
pthread_create(&s1, NULL, thread1, NULL);
pthread_create(&s2, NULL, thread2, NULL);
pthread_create(&s3, NULL, thread3, NULL);
sleep(1);
printf("Main thread end\n");
exit(0);
}
从结果可以看出,3个线程都能得到共享变量,但是得到共享变量的时间是不固定的。
5.编写一个多进程多线程的程序:要求创建4个子进程,每个子进程都分别
创建两个线程,进程和线程的功能不做要求,可以只提供简单的打印语句。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void* thread1_1(void *arg){
printf("thread1_1 is running\n");
return NULL;
}
void* thread1_2(void *arg){
printf("thread1_2 is running\n");
return NULL;
}
void* thread2_1(void *arg){
printf("thread2_1 is running\n");
return NULL;
}
void* thread2_2(void *arg){
printf("thread2_2 is running\n");
return NULL;
}
void* thread3_1(void *arg){
printf("thread3_1 is running\n");
return NULL;
}
void* thread3_2(void *arg){
printf("thread3_2 is running\n");
return NULL;
}
void* thread4_1(void *arg){
printf("thread4_1 is running\n");
return NULL;
}
void* thread4_2(void *arg){
printf("thread4_2 is running\n");
return NULL;
}
int main(void)
{
pid_t p1, p2, p3, p4;
pthread_t s1_1, s1_2, s2_1, s2_2, s3_1, s3_2, s4_1, s4_2;
p1=fork();
if(p1>0)
{
p2=fork();
if(p2>0)
{
p3=fork();
if(p3>0)
{
p4=fork();
}
}
}
if(p1==0){
printf("p1 is runnning, parentPid is %ld\n", getppid());
pthread_create(&s1_1, NULL, thread1_1, NULL);
pthread_create(&s1_2, NULL, thread1_2, NULL);
}
else if(p2==0){
printf("p2 is runnning, parentPid is %ld\n", getppid());
pthread_create(&s2_1, NULL, thread2_1, NULL);
pthread_create(&s2_2, NULL, thread2_2, NULL);
}
else if(p3==0){
printf("p3 is runnning, parentPid is %ld\n", getppid());
pthread_create(&s3_1, NULL, thread3_1, NULL);
pthread_create(&s3_2, NULL, thread3_2, NULL);
}
else if(p4==0){
printf("p4 is runnning, parentPid is %ld\n", getppid());
pthread_create(&s4_1, NULL, thread4_1, NULL);
pthread_create(&s4_2, NULL, thread4_2, NULL);
}
else{
printf("main is running, Id = %ld\n", getppid());
}
sleep(1);
exit(0);
}
进程创建的顺序和时间不固定,在进程创建完成后,在空闲状态下,打印“main is running, Id = %ld\n”, getppid()”
打印完成后,接着创建剩下的进程。进程创建完成后,每个进程各自创建两个线程。
五、遇到的问题及解决方法
问题1:实验一中主线程退出时,子线程也跟着退出。
解决:如果不在主线程退出之前让其休眠一段时间,就会导致子线程还未打印“已创建”语句时,子线程已经跟随主线程结束。因此,也看不到子线程已创建的语句。
问题2:出现进程ID是负数的情况。
解决:因为ID超出了整形的范围,需要改为长整型%ld。
本次实验涉及到的与线程相关的新函数很多,要想了解代码的执行过程就得先从函数的用法与功能入手。通过本次实验,我深入了解了进程的创建、执行、等待和退出等过程,并掌握了进程管理的基本操作。通过实验,我学会了如何编写进程管理程序,还加深了对操作系统原理的理解。
实验六 进程间通信
一、实验目的
了解Linux系统的通信机制,管道、消息队列、信号量的创建与使用、共享
内存。
二、预习报告
管道(pipe):管道是一种半双工的通信方式,数据只能单方向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系或者兄弟关系。
有名管道(named pipe):有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
信号量(semophore):信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止当某进程正在访问共享资源时,其它进程也访问该资源。因此主要作为进程间以及同一进程内不同线程之间的同步手段。
消息队列(message queue):消息队列是由消息的链表,存放着内核中并由消息队列标识符标识。消息队列克服了信号传递信息量少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号(signal):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已发生。
共享内存(shared memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建但是多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量配合使用,来实现进程间的同步和通信。
套接字(socket):套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。
1.管道的创建:
Linux下创建管道可以通过函数pipe来完成。该函数如果调用成功返回0,并且数组中将包含两个新的文件描述符;如果有错误发生,返回-1。该函数原型如下:
#include<unistd.h>
int pipe(int fd[2])
注意:管道只有通信双方同时存在时,才可以进行通信。
三、实验内容与结果记录
3.1 管道
(1).管道的创建
结果分析:
1. 利用pipe函数创建一个管道,如果返回值为0,则创建成功;返回值为-1,创建失败。
2. 调用fork函数创建一个新的子进程,注意必须在系统调用fork()之前调用pipe(),否则子进程将不会继承
管道的文件描述符。
3. 管道fd[0]端只能用于读,称 其为管道读端;fd[1]端则只能用于写,称其为管道写端。如果试图从管道 写端读取数据,或者向管道读端写入数据都将导致错误发生。
4. 当管道中父进程没有写入数据时,而子进程使用read读管道中的数据时,read将一直阻塞,等待管道中 写入数据。
补充:
文件描述符:File descriptor,简称fd,当应用程序请求内核打开/新建一个文件(资源)时,内核会返回一个文件描述符用于对应这个打开/新建的文件,其fd本质上就是一个非负整数。索引值,指向内核为每一个进程所维护的进程打开文件的记录表。
(2)父进程创建子进程后向子进程传递参数
1.被监控子进程接受监控主进程命令,执行不同的操作。这在实际项目中是经常见到的,监控进程启动加载多个具有不同功能的子进程,并通过管道的形式向子进程传递参数。
3.2 消息队列
1. 消息的创建与读写
分析:
1.key_t ftok(const char *pathname,int proj_id);
ftok函数根据pathname和proj_id这两个参数生成惟一的键值。该函数执行成功会返回一个键值;失败返回-1。
2.参数pathname在系统中一定要存在且进程有权访问,参数proj_id的取值范围为1~255。
3.ftok函数根据“.”和 i 这两个参数生成唯一的键值。该函数执行成功会返回一个键值,经过for循环,循环输出五个键值。
2.写消息队列
结果分析:
1.消息队列是一个存放在内核中的消息链表,每个消息队列由消息队列标识符标识。与管道不同的是消息队列存放在内核中,只有在内核重启或者显式地删除一个消息队列时,该消息队列才会被真正的删除。
2.可以通过ipcs(查看系统中进程间通信(IPC)资源)命令查看,结果显示向消息队列放入了两条消息 。
3. Int msgget(key_t key,int msgflg) 获取/创建消息队列
msgflg:消息队列的创建标志,包括以下选项:
IPC_CREAT:如果不存在,则创建消息队列。
IPC_EXCL:如果已经存在,则返回错误。
权限标志:指定消息队列的权限。
4. int msgsnd(int msqid,struct msgbuf *msgp,size_t msgsz,int magflg); 写消息队列
msqid:函数向msgid标识的消息队列发送一个消息。
msgp:msgp指向发送的消息。
msgsz:要发送的消息的大小,不包含消息类型占用4个字节。
magflg:操作标志位。可以设置为0或者IPC_NOWAIT。如果msgflg为0,则当消息队列msgsnd函数成功返回0,失败返回-1。常见错误有:EAGAIN,说明消息队列已满;EIDRM,说明消息队列已被删除;EACCESS,说明无权访问消息队列
3.读消息队列
结果分析:
rcvmsg.c通过ftok()获取键值,msgget()获取消息队列的标识符,msgrcv()读取sendmsg.c写入的数据,最后输出结果Get message Hello,message queue。
分析:
rcvmsg.c通过ftok()获取键值,msgget()获取消息队列的标识符,msgrcv()读取sendmsg.c写入的数据,最后输出结果Get message Hello,message queue。
3.3 信号量
分析:
server创建一个信号集,并对信号集循环减1,相当于分配资源。Client执行时检查信号量,如果其值大于0代表有资源,继续执行,并输出可用资源数。如果小于0代表资源已经分配完毕,进程client退出。Server程序显示资源已经用完。
3.4 共享内存
分析:
server创建一个信号集,并对信号集循环减1,相当于分配资源。Client执行时检查信号量,如果其值大于0代表有资源,继续执行,并输出可用资源数。如果小于0代表资源已经分配完毕,进程client退出。Server程序显示资源已经用完。
createshm (".", 'm', SHM_SIZE)):
创建共享内存区,参数为路径、标识符、共享内存大小,返回共享内存id
‘m’是用于生成key值的参数之一,具体生成的key值是由ftok函数生成的,
生成的key值可以用于创建共享内存
shmat (shmid, (char *)0, 0)):
将共享内存区链接到进程的地址空间中,参数为共享内存区标识符、链接地址、标志位
返回一个指向共享内存区的指针
分析:
两个程序在进入共享内存前,首先都检查信号集中的信号是否为1,如果不为1,调用sleep()进入睡眠直到信号的值变为1.进入共享内存之后,将信号的值减1,这样就实现了互斥的访问共享资源。当writer程序输入数据时,reader程序就相应输出的输入的数据。
读者优先。在while循环中,读者先等待信号量,然后进行P操作,如果信号量的值为0,则读者进程会被阻塞,直到信号量的值大于0。在读者读取共享内存中的数据后,会进行V操作,将信号量的值加1,此时写者进程才能进行写操作。因此,读者进程优先执行,写者进程需要等待读者进程完成读取操作后才能进行写入操作。
函数参数说明:
semctl (sid, index, SETVAL, semopts):
sid表示信号量集的标识符、index表示信号量在信号量集中的索引、
SETVAL表示设置信号量的值、semopts表示传递给semctl函数的参数。
(semctl(semid, 0, IPC_RMID)):
删除指定的信号量集,并释放相关的内核资源。
参数为信号量集的标识符、0表示第一个信号量、IPC_RMID表示要删除该信号量集。
semctl (semid, index, GETVAL, 0):
semid表示指定的信号量集的标识符;index表示指定的信号量在信号量集中的索引;
GETVAL表示获取信号量的当前值;0表示在获取信号量值时不需要传递额外的参数。
返回指定信号量的当前值
四、遇到的问题及解决方法
总结:
1.管道数据的读出和写入特点:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
2.在写入管道的函数write_to_pipe中,如果写入的数据长度超过了管道的缓冲区大小,可能会导致数据的丢失。可以使用循环写入的方式,保证写入完整的数据。
3.在子进程中,没有进行异常处理,如果读取管道失败,会直接退出进程。可以添加错误处理的代码,保证程序的健壮性。
实验七 存储器管理
一、实验目的
理解内存页面调度原理、掌握几种理论页面置换算法的实现方法、通过实验 比较各种调度算法的优劣;页面置换算法是虚拟存储管理实现的关键,通过本次实验理解内存页面调度的机制,在模拟实现FIFO、LRU、NRU和OPT几种经典的页面置换算法的基础上,比较各种置换算法的效率及优缺点,从而了解虚拟存储实现的过程。
二、预习报告
通过预习,我学会了以下几种页面置换算法:
1)先进先出的算法FIFO:按照页面进入内存的时间顺序进行置换,先进入内存的页面先被置换出去。缺点是无法考虑页面的使用频率和重要程度。
2)最近最少使用的算法LRU:根据页面最近一次被访问的时间来进行置换,最近被访问时间最久的页面会被置换出去。优点是能够考虑页面的使用频率,但是实现较为复杂。
3)最近未使用的算法NUR:根据页面最近一次被使用的时间和是否被修改来进行置换,未被使用且未被修改的页面优先被置换。优点是能够考虑页面的修改情况,但是需要额外的硬件支持。
4)理想形算法OPT:预测未来的页面访问情况,将未来最长时间内不会被访问的页面置换出去。优点是能够最大程度地减少页面置换次数,但是实现难度极大且无法实现。
三、实验内容与结果记录
通过控制台显示的结果可以粗略看出,不管哪种页面置换算法,命中率都会随着内存页数的增加而上升。
通过对各种页面置换算法的对比可以看出,OPT页面置换算法的命中率一直高于另外其它三种置换算法。
其余三个页面置换算法的命中率差别不大,在内存页面数为17页时,LRU和NUR算法对于FIFO算法有比较大的领先。在内存页面数达到29页的时候,四种页面置换算法命中率都在0.9。
四、遇到的问题及解决方法
1、代码遗漏一些必要的头文件造成警告,如stdio.h、stdlib.h、string.h。
2、在LRU算法中,在页面失效时,应该将_pFreepf_head指向空闲页面链表的下一个结点,而不是上一个结点,否则会出现重复使用同一个页面的情况。
本次实验内容的难点在于对四种页面置换算法的理解。要根据页面数增加时四种置换算法命中率的变化、命中率大小关系变化进行分析,结合置换算法实质对结果做出分析。
实验八 Linux文件系统
一、实验目的
通过本实验:
(1)使用控制字符执行特殊功能; 使用 file 和 strings 命令确定文件类型; 使用 cat 利 more 命令显示文本文件的内容;使用 head 和 tail 命令显示文本文件的部分内容;使用 wc 命令确定单词、行和字符数;使用 diff 命令比较 2 个文件。回顾文件和目录命名约定;使用 touch 命令创建新文件;使用mkdir 命令创建新目录;使用 rm 命令删除文件;使用 rm -r 命令删除目录。
(2)显示文件系统权限。确定文件的用户权限、属组权限或其他 (公共) 权限。确定对于一个可执行文件的文件权限。使用默认权限创建一个文件或目录。从命令行中修改权限: 使用文件系统来控制安全访问。使用符号模式修改文件或目录的权限。使用八进制模式修改文件或目录的权限。使用 vi 编辑器创建一个脚本文件,并且使它可执行。访问文件管理器,使用文件和目录权限工作;使用文件管理器确定文件或文件夹的权限;使用文件管理器修改文件或文件夹的权限。
二、预习报告
1.什么是GNOME?
GNOME是一套纯粹自由的计算机软件,运行在操作系统上,提供图形桌面环境。
GNOME 包含了 Panel (用来启动此程式和显示目前的状态)、桌面 (应用程式和资料放置的地方)及一系列的标准桌面工具和应用程式,并且能让各个应用程式都能正常地运作。
2. 在Linux系统中,一切都是文件。文件可以是文本文件、图片文件、音频文件、视频文件等等。每个文件都有一个文件名和一个路径,文件名用于识别文件,路径则用于指定文件在文件系统中的位置。
3. 目录是一种特殊的文件,它可以包含文件和其他目录。每个目录也有一个名称和一个路径。在Linux系统中,根目录是文件系统的顶层目录。
4. 通过预习我学到了一些命令的语法和功能,比如确定文件类型的file和strings命令,还有使用head和tail命令显示文本文件的部分内容等等。
三、实验内容与结果记录
1. 文件信息命令 13步
(1)man ls 再 ctrl+z终止输出
(2)bc打开计算器
使用计算器时,我没有提示符?
(3)ctrl+U直接擦除整行
(4)file确定文件类型
(5)strings打印可执行文件或者二进制文件中的可读字符。
(6)cat显示文件的内容
显示的是dev1文本文件的内容,一个屏幕显示不全,必须按滚动条才能看全部文本内容
(7)more用于显示文本文件首选的方法,因为它会自动的一次显示一屏文件内容
按下回车键继续显示下一行内容:
如果文件的信息比一屏更长,屏幕的底部显示如下的信息:
--More-- (n%) (文件的 n%已经显示) 。按下回车键,继续一次显示一行信息。空
格键将继续一次显示一屏内容。
(8)head 命令用于显示一个或多个文本文件的前 n 行
显示了前十行
指定显示前20行:
(9)使用 tail 命令,显示文件的最后几行
默认显示最后十行。
(10)wc (单词计数) 命令可以用于显示文本文件的行数、单词数、字节数或者字符数。
(11)使用 wc 和 ls 命令确定主目录中条目 (文件和目录) 的数目
行数为210 ;单词数210 ;字节数为1286
(12)diff (不同) 命令用于比较 2 个文本文件,找出在它们之间的不同之处
第3行和第5行不同
cat查看文件内容
可以使用哪 2 个命令来确定 2 个文件是否相同?
可以用diff命令来比较是否相同
(13)关闭终端窗口,注销
使用exit退出。
2. 基本的命令行文件管理
(1)文件名\目录名合法性判断
表 8-1 实验记录
文件名 | 是否为 Linux 文件或目录名 | 为什么是或为什么不是 |
12345abcde678 | 是 | 目录名没超过256 个字符 |
Hobbies: 2 | 不是 | 因为中间有一个空格,文件或者目录名中间不能有空格。所以实际上会创建两个文件:Hobbies:和 2文件 |
Adcd-123 | 是 | “-”非数字字母字符或者元字符是可用的 |
Sales*repts*2001 | 不是 | “*”字符对于 shell 有特殊的意义 |
D.projects.bj.2001 | 是 | “.”表示扩展名 |
Projects>1.bj-2001 | 不是 | 小于号 (<) 和大于号 (>) 是不允许作为文件名的 |
(2)使用 touch 命令,可以同时创建一个或多个文件
1)使用touch filenew创建新文件
2)touch后面可以加多个文件用空格隔开 ;使用touch newfile 创建名为newfile的文件
3)ls显示所有文件
4)ls -l +文件名查看文件所有者
5)查看组命令 cat /etc/group
6)stat newfile查看创建时间
7)文件大小以及创建时间都可查看
8)file查看文件类型
9)touch new1 new2 new3创建三个文件
10)ls查看文件
3. 确定文件系统权限及在命令行中修改权限 1-19
步骤 1:开机,登录进入 GNOME。
步骤 2:访问命令行。
步骤 3:显示权限。
权限控制着谁能够对文件系统中的文件和目录做什么。目录和文件权限可以使用带 –l (长列表) 选项的 ls (列表) 命令来确定。ls -l 命令显示目录内容的长列表。如果同时给出 -a 选项,则所有文件,包括隐藏文件和目录 (那些以圆点打头的) 都被显示出来。
表 8-2 提供了检查使用 ls -l 目录列出的信息。
1)ls的第一个位置“-”代表一个普通的文件对文件或目录列表“d”表示文件类型。使用ls -l命令列出主文件夹中的文件。/bin/cat 的文件类型是什么 (文件或目录) ?如何知道的?
可执行文件,通过用户权限可以知道,另外它是绿色的
- 接下来的 ls 中的 9 个位置 用户、同组用户、其他 表示文件的权限。所有文件或目录可能的权限是:(小写) r、w、x 或短横线 (-) 。cat 的权限是什么?
r w x 可读 可写 可执行
步骤 4:解释权限。
请参阅表 8-3,回答下面的问题。注意到权限的解释对于文件和目录是不同的。
- 文件的 r 权限的意义是什么?
文件只有可读权限,可以被读取或者拷贝。但不能删除和移动。
- 目录的 r 权限的意义是什么?
列出目录下的文件,必须拥有使用ls命令选项的权限。
- 文件的 x 权限的意义是什么?
文件可以执行。
- 文件的 w 权限的意义是什么?
文件可写,文件可以被修改、移动和删除。
- 目录的 w 权限的意义是什么?
可以在目录下建立和删除文件和目录。目录也要有执行权限才行。
- 权限位置的短横线 (-) 的意义是什么?
表示因为权限问题被拒绝。
步骤 5:确定文件的用户权限。
九个权限被分成三个权限一组。每组的三个权限总是按照 r (读)w(写)和 x(执 行)的顺序排列。如果权限不允许,短横线 (-) 将在它的位置。第 1 组三个权限 是用户的权限组。这些权限决定其所有者能够做什么。
在主目录中创建文件 dante。在“应用程序”菜单中单击“附件”-“文本编辑器”命令,在文本编辑中键入适当内容并保存为 dante。
1)谁是 dante 文件的所有者?
当前登录的用户stelayuri
2)用户权限的头 2 个字符是什么?
rw
3)在用户的权限组中,第 3 个位置是什么?
-,表示不可执行
- 列出根据所给的文件权限,用户 (所有者) 能够做的 4 件事情。
拷贝、移动、删除和修改
步骤 6:确定文件的属组权限。
系统管理员给每一个用户分配了一个主属组。这个文件所有者所在的属组是一个当该文件创建时,随所有者一起分配的成员。第 2 组的 3 个权限决定了主属组的成员能够做什么。
- dante 文件的所有者是什么主属组的成员?
stelayuri
- 属组权限的第一个字符是什么?
r
- 这允许属组的其他成员对文件进行什么操作?
可读,文件可以显示也可以拷贝
- 为什么在接下来的第二和第三个位置不是 w 和 x,而是短横线?
因为只可读不可写,因此文件不能移动、修改和删除
步骤 7:确定文件的其他 (公共) 权限。
最后一组字符,叫做其他权限,是其他每一个人都有的权限。其他指既不是文件所有者也不是文件所有者所在属组的成员,但是有权访问系统的所有人。
不是所有者和属组的其他人对 dante 文件有什么权限?
可读文件,只有读取和拷贝的权限
步骤8:确定可执行文件的文件权限。
可执行文件,例如Linux工具程序和脚本文件,对于想执行命令或者脚本的所有人要求 (执行) 权限。
1) 从主目录中显示在 /usr/bin目录中的bc文件的长目录列表。使用什么命令?
ls –l /usr/bin/bc_
2) 文件的权限是什么?
rwxr-xr-x_____
3) 用户权限是什么?
rwx可读可写可执行___
4) 属组权限是什么?
r-x__
5) 其他权限是什么?
r-x__
6) 为什么组属用户和其他用户类别没有w (写) 权限?
因为其他用户不被允许修改,只有超级用户才有修改权限 _
步骤9:使用默认权限创建一个新文件。
使用默认权限创建新文件。使用touch命令在主目录中创建一个新文件。
1) 在主目录中创建一个叫做newfileperms的新文件。使用什么命令和路径名?
touch newfileperms__
2) 查看newfileperms的权限。使用什么命令和路径名?
ls –l newfileperms_
3) 分配给这个文件的默认权限是什么?
rw-__rw- r--_
4) 谁是所有者?
stelayuri_
5) 谁是主属组?
stelayuri_
6) 主属组的成员能够重新命名这个文件吗?
能
步骤10:使用默认权限创建一个新目录。
也可以使用不同的默认权限创建新目录。使用mkdir命令在主目录中创建一个新目录。
1) 在主目录的practice目录中创建一个叫做newdirperms的新目录。使用什么命令和路径名?
mkdir newdirperms_
2) 列出主目录中的内容,查看newdirperms的权限。使用什么命令和路径名?(注:先退回到主目录的上级目录中。)
ls –al mewdirperms___
3) 分配给这个目录的默认权限是什么?
rwx rwx r-x__
4) 谁是所有者?
stelayuri_
5) 谁是主属组?
stelayuri_
6) 一个主属组的成员能够在这个目录中添加文件吗?
可以_
步骤11:回顾chmod命令模式。
chmod (修改模式) 命令被文件所有者 (或超级用户) 用来修改文件权限。chmod命令的2种操作模式是符号 (或相对) 和八进制 (或绝对) 。chmod命令通用的格式是:
chmod mode filename
模式部分会根据是使用符号模式还是使用八进制模式而做修改。
· 符号模式:使用字母与符号的组合,为不同类别的用户添加或删除权限。符号模式也叫做相对模式。
· 八进制模式:使用数字表示文件权限。八进制模式也叫做绝对或者数字模式。
1) 哪种chmod模式使用数字表示文件权限?
八进制模式__
2) 哪种chmod模式使用字母 (或符号) 表示权限?
符号模式_
步骤12:使用符号模式修改文件权限。
当使用符号模式设定权限的时候,尽管会同时给所有类别的用户同样的权限,一般只对一种类别的用户工作。这个模式叫做相对模式,因为正在相对已经存在的权限进行分配或删除权限。可以给一个特定类别的用户添加或删除一个或多个权限,或者把权限都取走。符号模式的命令格式使用字母和符号。命令格式的模式部分由3个部分组成:
· 谁:要处理的用户的类别:u = 用户,g = 属组, o = 其他,还有a = 所有。
· 操作:操作或者想做的事情:设定 (=) ,删除 (-) ,给予 (+) 。
· 权限:分配的权限:r = 读,w = 写,还有x = 执行。
下面的例子删除 (-) 了文件dante中其他 (o) 类别用户的读 (r) 权限。 注意:在o 短横线 (-) 和r之间没有空格。
chmod o-r dante
下面的例子给文件dante添加 (+) 了属组 (g) 和其他 (o) 类别用户的写 (w) 权限:
chmod go+w dante
1) 在主目录中使用相对路径名创建一个叫做chmoddir的新目录。使用什么命令创建目录?
mkdir chmoddir_
2) 改变到chmoddir目录中,创建一个叫做symfile的新文件。使用什么命令创建文件?
touch symfile_
3) 使用ls -l命令来确定symfle的权限。这些是文件的默认权限。用户、属组和其他的权限是什么?
rw- rw- r--_
4) 决定不想让其他用户 (除了自己和属组成员之外) 能够查看symfle的内容和拷贝symfle。使用chmod命令,在符号模式下,删除其他用户对于文件symfle的读权限。使用什么命令?
chmod o-r symfile_
5) 再次列出文件的权限。其他类别用户的权限现在是什么?
---__
6) 如果想只使用一个命令删除属组和其他类别的读权限,使用什么命令?
chmod go-r symfile_
步骤13:使用符号模式修改目录权限。
1) 改变回到主目录,使用什么命令?
cd __
2) 从主目录中列出早先创建的新的chmoddir目录的权限。这些是目录的默认权限。用户、属组和其他的权限是什么?
rwx rwx r-x_
3) 除了自己或者属组成员以外的其他用户能够从chmoddir目录中拷贝文件吗?
能_
为什么能或者为什么不能?
因为其他用户的权限是r-x,有权限可以查看和拷贝
4) 不想让其他用户从chmoddir目录中拷贝文件。改变到主目录中,使用chmod命令,在符号模式下,删除其他类别用户对于目录chmoddir的读和执行权限。使用什么命令?
chmod o-rx chmoddir_
5) 再次列出目录的权限。其他类别用户的权限是什么?
---_
6) 改变到主目录,使用chmod命令,在符号模式下,给主属组去除对目录chmoddir的读权限。使用什么命令?
chmod g-r chmoddir_
7) 通过使用符号模式把权限改回默认的权限。使用什么命令?(提示:属组和权限可以使用一个命令组合,或者可以使用2个分离的命令。)
_chmod go+rx chmoddir
步骤14:确定八进制权限。
八进制模式为同时修改所有类别用户的权限提供了一个快捷的数字方式,而且仍然允许每组权限可以是不同的。有3组可能的权限 (r、w和x) ,对应于每种用户类别 (用户、属组或其他) 。每组权限可以根据允许的权限使用数字 (0到7) 来分配。
r (读) 权限指派为数字4,w (写) 权限指派为数字2,x (执行) 权限指派为数字1。通过添加数字,我们得到一个总的对应于用户类别 (用户、属组或其他) 的3个权限。例如,如果用户 (所有者) 对于文件的权限是rwx,我们把4 (读) 加上2 (写)加上1 (执行) 得到7。如果属组有rw权限,它们得到4+2+0 (没有执行权限) 的总数6。如果其他只有r权限,它们得到4+0+0 (没有写和执行权限) 的总数4。这个文件或目录的octal_mode是764。
1) 通过把字符权限转换成等效的八进制,填入表8-4。先转换每组权限 (用户、属组或其他) ,然后在八进制模式权限下输入octal_mode (3个数字) 。
用户权限 | 八进制数 | 属组权限 | 八进制数 | 其它权限 | 八进制数 |
rwx | 7 | rw-- | 6 | rw-- | 6 |
rw- | 6 | r-- | 4 | r-- | 4 |
r-- | 4 | r-- | 4 | r-- | 4 |
rwx | 7 | r-x | 5 | r-x | 5 |
步骤15:使用八进制模式修改文件权限。
使用八进制模式,没有必要指定用户的类别,因为每个数字的位置表示了三种用户类别中的一种。Octal_mode由三个数字组成,每个都是一种用户类别 (用户、属组或其他) 的总和。八位数值组合在一起标识了用于chmod命令的octal_mode。
chmod octal_mode filename
1) 改变到chmoddir目录中,创建一个叫做octfile的新文件。使用什么命令创建文件?
touch octfile_
2) 使用ls -l命令来确定octfile的权限。这些是文件的默认权限。什么是用户、属组和其他的数字权限?
rw- rw- r--__
3) 与这个文件的用户、属组和其他权限等同的八进制模式是什么?
664__
4) 决定不想让其他用户能够查看或者拷贝octfile文件的内容。使用chmod命令,在八进制模式下,删除其他用户对于octfile的r (读) 权限。使用什么命令?
chmod 640 octfile _
5) 再次列出文件的权限。其他用户类别现在的权限是什么?
---__
6) 如果想只使用一个命令,删除属组和其他类别的所有权限,使用什么命令?
__chmod 600 octfile _
步骤16:使用八进制模式修改目录权限。
下面的格式用于修改目录的权限。-R (递归) 选项修改指定目录的权限,包括其中的所有子目录和文件。
chmod [-R] octal_mode directoryname
1) 改变到主目录。使用什么命令?
cd
2) 从主目录中列出chmoddir目录的权限。这些是目录的默认权限。对于用户、属组和其他,数字极限是什么?
rwx rwx r-x_
3) 什么是和用户、属组和其他对于这个目录等同的八进制模式?
_775__
4) 使用chmod命令,在八进制模式下,删除其他类别用户对于目录chmoddir的读和写权限。使用什么命令?(记住:在八进制模式下,必须总是指定所有的3组权限,即使它们可能没有被修改。)
_chmod 771 chmoddir
5) 再次列出目录的权限。其他用户类别的权限现在是什么?
_--x___
用户和属组的权限保持不变吗?
保持不变__
- 全属组 (核心组) 成员能够在 chmoddir 目录中创建新文件或者拷贝文件 吗?为什么能或者为什么不能?
可以拷贝,因为有rwx权限
7) 决定让属组成员能够从你的目录中拷贝文件。改变到主目录,使用chmod命令,在八进制模式下,给主属组 (核心组) 添加对目录chmoddir的写权限。用户有权限rwx,属组应该有权限rw,其他应该对目录没有权限。使用什么命令?
__chmod 760 chmoddir _
8) 使用八进制模式把权限改回默认权限 (rwxr-xr-x) 。
__chmod 755 chmoddir
步骤17:创建一个脚本文件,使它能够执行。
在本步骤中,将使用vi编辑器创建一个简单的文本脚本文件。为了能够运行脚本文件,然后需要使它可以执行。脚本文件在帮助自动重复作业的时候非常有用。
1) 改变到chmoddir目录,使用vedit启动vi编辑器。当启动编辑器的时候,指定或者打开一个新文件叫做myscript。按下i进入插入输入模式,以小写文本键入下面的命令。在每行后按回车键。
echo “hello!”
2)按下 ESC 键,返回命令模式,然后输入一个冒号,进入末行模式。按下wq 来写入 (保存) 文件,然后退出 vi。
3)列出文件,确定它的权限。它们是什么?
rw- rw- r--
4)键入 ./myscript,就像它是一个命令,然后按下回车键。命令的响应是什么?
权限不够
5)修改 myscript 的权限,这样用户权限包括 x (执行) ,作为所有这可以执行或运行文件。可以使用符号模式或者八进制模式。使用什么命令修改权限?
chmod u+x myscript
6)列出文件,检查修改的权限。用户 (所有者) 现在的权限是什么?
rwx rw- r--
7)再次把 myscript 作为一个命令键入,然后按下回车键。命令的响应是什么?
Hello!
步骤18:删除在本实验中创建的文件和目录。
删除在本实验过程中在你的主目录中创建的所有文件和目录。
步骤19:关闭终端窗口,注销。
四、遇到的问题及解决方法
问题1:使用chmod或chown命令来修改权限,但是无法修改。
解决方法:查资料发现是没有足够的权限,需要使用sudo命令获得管理员权限。
问题2:使用rm命令删除文件或rmdir命令都无法删除文件夹
解决方法:,查资料发现是因为文件或文件夹被其他进程占用或者没有足够的权限。先使用lsof命令查找占用该文件或文件夹的进程,再使用sudo命令获得管理员权限就能删除了。
问题4:文件系统出现错误无法读写
解决方法:使用fsck命令检查文件系统,并修复错误。
总结:
本次实验主要针对Linux系统的常用功能、文件形式、权限管理等基本内容进行了学习与掌握,并全部手动操作了一遍。需要理解的地方很多,所以比较多的地方上网搜索了相关资料后先学再做、现学现用。在实验过程中学到了Linux文件的一些基本操作命令,这么多命令也不可能全部记住,只需要记住常用的,不常用的就需要在用到的时候再去搜索相关的资料。