linux期末考试题(3)
linux期末考试题
一、选择题(共20分,每小题2分)
1.为了达到使文件的属主和同组用户有读(r)、写(w)和执行(x)的权限,而其他用户只能进行只读访问,在设置文件的许可值时,应当设置为(B)。
A.747 B.744 C.775 D.744
解答:
读:4 写:2 执行:1
属主权限:4+2+1=7
同组权限:4+2+1=7
其他用户权限:4
2.在linux系统中,要让某个进程在3天后下午2:10执行,可以用哪个命令?(B)
A.cron 2:10pm +3day B.at 2:10pm +3day C.tar 2:10pm +3day D.run 2:10pm +3day
解答:
at
命令用于在指定时间执行一次性任务。
cron
是用于定时任务的守护进程,但它是用来配置周期性任务(如每天、每周执行),而不是一次性任务。
tar
是用于归档文件的工具,与任务调度无关。
run
不是标准的Linux命令,通常用于特定环境(如某些开发工具),不适用于此场景。
3.下面哪个命令可以分页显示内容(C)
A.pause B.cat C.more D.grep
解答:
pause
不是Linux中用于分页显示内容的命令。实际上,在标准的Linux命令集中,并没有一个名为 pause
的命令用于此目的。它可能出现在其他上下文(如某些脚本语言或特定环境)中。
cat
命令用于将文件内容输出到标准输出(通常是终端)。它不会分页显示内容,而是直接连续显示整个文件。如果文件很大,内容会快速滚动通过终端,难以阅读。
more
命令用于分页显示文件内容。它会一次显示一页内容,并等待用户输入(如空格键翻页或回车键逐行查看)来继续显示下一页。
grep
命令用于在文件中搜索匹配特定模式的行,并将这些行输出到标准输出。它不用于分页显示文件内容,而是用于文本搜索和过滤。
4.linux操作系统结构由什么组成(ABCD)
A.linux内核 B.Linux Shell C.linux文件系统 D.linux应用程序
解答:
内核是操作系统的核心部分,负责管理系统的硬件资源(如CPU、内存、磁盘I/O等),并提供给上层应用程序一个统一的接口。Linux内核是开源的,并且具有高度的可定制性和灵活性。它是Linux操作系统的基础,负责处理系统的基本功能,如进程管理、内存管理、文件系统管理、设备驱动等。
Shell是用户与操作系统之间的接口,它接收用户输入的命令,并解释执行这些命令。Shell还提供了脚本编程的能力,允许用户编写自动化任务。常见的Shell有Bash、Zsh、Ksh等。Shell是用户与Linux内核交互的桥梁,使得用户可以通过文本命令来控制系统。
文件系统负责组织和管理存储在磁盘上的文件和目录。Linux支持多种文件系统,如ext4、XFS、Btrfs等。文件系统提供了数据的存储、检索、修改和删除等功能。它是Linux操作系统中数据组织和管理的基础,确保了数据的持久性和可访问性。
应用程序是运行在Linux操作系统上的软件程序,它们提供了各种功能和服务,如文本编辑、图形处理、网络通信、数据库管理等。Linux操作系统上有大量的开源应用程序可供选择,用户可以根据自己的需求安装和使用这些应用程序。应用程序是Linux操作系统功能扩展和用户需求满足的重要部分。
5.下面哪几个符号是linux的通配符(CD)
A.# B.@ C.? D.*
解答:
在Linux中,通配符用于在命令行中匹配文件名或路径名,从而简化命令的输入和操作。
#
符号在Linux中通常用作注释的开始符号,在Shell脚本或命令行中,#
后面的内容会被视为注释,不会被执行。
@
符号在Linux中并没有特定的通配符功能。它可能在某些特定的上下文或应用程序中有特殊含义,但在标准的Linux命令行通配符中,@
并不被用作通配符。
?
是Linux中的一个通配符,用于匹配单个字符。例如,file?.txt
可以匹配 file1.txt
、file2.txt
等,但不会匹配 file12.txt
(因为 ?
只能匹配一个字符)。
*
是Linux中最常用的通配符之一,用于匹配任意数量的字符(包括零个字符)。例如,*.txt
可以匹配当前目录下所有以 .txt
结尾的文件。
6.想要把当前目录下的file1.txt复制为file2.txt,正确的命令是(B)
A.copy file1.txt file2.txt B.cp file1.txt file2.txt C.cat file1.txt file2.txt D.cat file1.txt>file2.txt
解答:
copy
是 Windows 系统中的命令,不是 Linux/Unix 系统的命令。
cat
命令用于连接文件并打印到标准输出设备上。如果直接写 cat file1.txt file2.txt
,会将两个文件的内容连续显示在终端,而不会创建或复制文件。
cat file1.txt > file2.txt
会将 file1.txt
的内容重定向到 file2.txt
(覆盖 file2.txt
的原有内容)。虽然效果上类似于复制,但这不是标准的复制命令,且如果 file2.txt
已存在,会直接覆盖而不提示。
7.更改一个文件权限的命令是(C)
A.change B.attrib C.chmod D.at
解答:
change
不是 Linux/Unix 系统中用于更改文件权限的标准命令。
attrib
是 Windows 系统中用于查看或更改文件属性的命令,不是 Linux/Unix 系统的命令。
chmod
(change mode)是 Linux/Unix 系统中用于更改文件或目录权限的标准命令。可以通过数字模式(如 chmod 755 file.txt
)或符号模式(如 chmod u+x file.txt
)来设置权限。
at
是 Linux/Unix 系统中用于在指定时间运行任务的命令,与文件权限无关。
8.以下哪种不是linux的shell类型(C)
A.bash B.ksh C.rsh D.csh
解答:
bash
是 Bourne Again SHell 的缩写,是Linux系统中广泛使用的默认shell,属于标准的shell类型。
ksh
是 Korn Shell 的缩写,是一种兼容Bourne Shell的高级交互式shell,属于shell类型。
rsh
是 Remote Shell 的缩写,主要用于远程命令执行,是一种网络协议或工具,而不是本地用户交互的shell类型。
csh
是 C Shell 的缩写,是一种语法类似C语言的shell,常用于BSD系统,属于shell类型。
9.linux系统目录中/boot存放的内容是(A)
A.存放系统的内核文件和引导装载程序文件 B.存放所有主要的库文件
C.应用程序存放目录 D.存放系统的大部分配置文件和子目录
解答:
/boot
目录是 Linux 系统中专门用于存放与系统启动相关的文件的目录。
主要的库文件通常存放在 /lib
(系统核心库)或 /usr/lib
(应用程序库)中。
应用程序通常存放在 /usr/bin
(二进制可执行文件)、/usr/sbin
(系统管理命令)或 /usr/local
(用户自行安装的软件)中。
系统的大部分配置文件通常存放在 /etc
目录中。
10.文件的 inode 数据结构包含以下哪些内容(BCD)。
A、文件名称 B、文件的访问权限 C、文件的链接数 D、文件数据 block 的位置
解答:
inode(索引节点)是Linux文件系统中用于存储文件元数据的数据结构。
inode中包含的信息通常包括:
- 文件的类型(如普通文件、目录、符号链接等)。
- 文件的访问权限(如读、写、执行权限)。
- 文件的硬链接数(即指向该inode的目录项数量)。
- 文件所有者的用户ID和组ID。
- 文件的大小(以字节为单位)。
- 文件数据块的指针(即文件数据在磁盘上的存储位置)。
- 文件的创建时间、修改时间、访问时间等时间戳。
inode中不包含的信息是文件名。文件名存储在目录项中,目录项将文件名映射到对应的inode号。
二、简答题(共50分,第6小题10分,其余小题8分)
1.什么是shell?shell主要起什么作用?
答:Shell 是用户与 Linux 操作系统交互的命令行解释器,主要作用是接收用户输入的命令并解析执行,同时提供脚本编程能力以自动化任务。它是操作系统内核与用户之间的桥梁,允许用户通过文本命令直接操作系统资源(如文件、进程等),并支持将复杂操作封装为脚本,实现高效的任务自动化。
2.什么是符号链接?什么是硬链接?符号链接与硬链接的区别是什么?
答:符号链接是独立文件,存储目标文件的路径(类似快捷方式),可跨文件系统或链接目录,若目标删除则链接失效;
硬链接是文件系统的另一个名称,直接指向原始文件的inode(数据块索引),与原始文件无本质区别,不可跨文件系统且不能链接目录,删除硬链接或原始文件不影响另一方,仅当所有硬链接被删除时文件数据才会释放;
区别:本质不同,符号链接是独立的“路径指针文件”,硬链接是原始文件的另一个“别名”(共享inode)。符号链接可跨分区/设备,硬链接不行。符号链接可链接目录或不存在的文件,硬链接只能链接文件(且不能是目录)。删除符号链接不影响原始文件,删除硬链接或原始文件中的任意一个,另一个仍可正常访问(直到所有硬链接被删除)。符号链接是“指向路径的指针”,硬链接是“原始文件的分身”。
3.执行命令ls -l时,显示结果如下:
-rwxrw-r-- 1 momo momo 2021 jul 28 18:58 test.c
(1)用户momo对该文件有什么权限?
答:用户momo对该文件有读、写、执行的权限。
(2)用户jojo和root都不是momo组的成员,他们对该文件具有什么访问权限?
答:用户jojo对该文件只有读权限,root作为超级用户,对该文件有读、写、执行权限,不受文件权限限制。
(3)如何使任何用户都可以读、写、执行该文件?请写出两种修改方式。
答:chmod a=rwx test.c chmod 777 test.c
(4)如何把该文件属主和属组改为用户tom?
答:sudo chown tom:tom test.c
4.某系统管理员每天需完成以下的重复工作,请按照(2)-(5)的要求编制一个任务调度。
(1)说出at作业和cron作业的基本区别,并说明完成本计划需编写哪种作业?
答:at作业:用于执行一次性任务,即在指定的绝对时间或相对时间运行一次。
cron作业:用于执行周期性任务,即按照设定的时间间隔或固定时间点重复执行。
由于系统管理员需要每天、每周定期执行任务,因此需要使用cron作业。
(2)每天早上9点将当前登录用户保存到useronline 文件中;
答:
0 9 * * * who >> /opt/usronline
(3)每周日凌晨零点零分定期备份/user/backup到/tmp目录;
答:
0 0 * * 7 cp /usr/backup /tmp
(4)每周五下午5:30删除临时文件(/temp目录中的所有文件)。
答:
30 17 * * 5 rm -rf /temp/*
(5)每星期日23:50将/data目录下的所有目录和文件压缩为backup.tar.gz 文件并归档。
答:
50 23 * * 7 tar -czvf /data/backup.tar.gz /data
5.现有一个 windows下使用过的U盘(U盘使用/dev/sdb1接口),要求在在此U盘上新建myfiles 目录,并在此目录下新建一文件soft,内容任意,再将该文件复制到/root 目录下,最后安全取出U盘,要求写出相关的命令行。
答:
# 查看 U 盘设备名称
lsblk
# 挂载 U 盘
mkdir -p /mnt/usb
mount /dev/sdb1 /mnt/usb
# 创建目录和文件
mkdir /mnt/usb/myfiles
echo "aaa" > /mnt/usb/myfiles/soft
# 复制文件到 /root
cp /mnt/usb/myfiles/soft /root/
# 安全卸载 U 盘
umount /mnt/usb
6.读下列程序my.sh的功能,以及读入命令行参数后的执行结果。
#!/bin/bash #计算所有命令行参数的和
#! filename: my. sh
sum=0 #初始化一个变量 sum,用于存储累加的结果
for INT in $* #for 循环,遍历所有的命令行参数,$* 表示所有的命令行参数
do
sum=`expr $sum + $INT` #expr命令算术运算,将sum值与参数INT相加再赋值给sum
done
echo $sum #输出累加的结果
运行#bash my.sh 1 2 3 4 5
解:当运行 bash my.sh 1 2 3 4 5
时,脚本会计算 1、2、3、4、5 的和,并输出结果。
?考点:
expr
的基本用法
#算术运算:
加法:expr $a + $b
减法:expr $a - $b
乘法:expr $a \* $b(注意:乘法运算符 * 需要转义,因为 * 在 Shell 中有特殊含义)
除法:expr $a / $b
取模:expr $a % $b
#比较运算:
相等:expr $a = $b
不等:expr $a != $b
大于:expr $a \> $b(注意:> 需要转义,因为 > 在 Shell 中有特殊含义)
小于:expr $a \< $b(注意:< 需要转义,因为 < 在 Shell 中有特殊含义)
#字符串操作:
字符串长度:expr length "$string"
字符串匹配:expr "$string" : "pattern"
#注意事项
空格:expr 的运算符和操作数之间必须有空格。例如,expr 1 + 2 是正确的,而 expr 1+2 是错误的。
转义字符:某些运算符如 * 和 > 在 Shell 中有特殊含义,因此在使用 expr 时需要转义它们。
返回值:expr 命令在成功时返回 0,失败时返回非零值。因此,可以通过检查退出状态来判断运算是否成功。
三、综合编程题(共30分,每小题10分)
1.shell编程,判断一个文件是不是块或字符设备文件,如果是则将其复制到/dev目录下。
解:
#!/bin/bash
# 指定要检查的文件路径
read -p "请输入要判断的文件名:" file_path
# 检查文件是否是块设备文件
if [ -b "$file_path" ]; then
echo "$file_path 是一个块设备文件。"
# 复制到 /dev 目录
cp "$file_path" /dev/
echo "已复制到 /dev 目录。"
elif [ -c "$file_path" ]; then
echo "$file_path 是一个字符设备文件。"
# 复制到 /dev 目录
cp "$file_path" /dev/
echo "已复制到 /dev 目录。"
else
echo "$file_path 不是一个块设备文件或字符设备文件。"
fi
2.用c语言编程,打开用户指定文件,将文件内容倒序后再写入该文件。
解:
代码一:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void reverse_file_content(const char *filename) {
FILE *file = fopen(filename, "r+"); //以读写模式打开文件
if (file == NULL) {
perror("Failed to open file");
exit(EXIT_FAILURE);
}
// 移动到文件末尾以获取文件大小
fseek(file, 0, SEEK_END); //获取文件的大小
long file_size = ftell(file); //获取文件的大小
fseek(file, 0, SEEK_SET);
// 分配内存以存储文件内容
char *buffer = (char *)malloc(file_size + 1);
if (buffer == NULL) {
perror("Failed to allocate memory");
fclose(file);
exit(EXIT_FAILURE);
}
// 读取文件内容,将文件内容读取到一个缓冲区中
if (fread(buffer, 1, file_size, file) != file_size) {
perror("Failed to read file");
free(buffer);
fclose(file);
exit(EXIT_FAILURE);
}
buffer[file_size] = '\0'; // 确保字符串以空字符结尾
// 倒序文件内容
for (long i = 0; i < file_size / 2; i++) {
char temp = buffer[i];
buffer[i] = buffer[file_size - 1 - i];
buffer[file_size - 1 - i] = temp;
}
// 将文件指针移动到文件开头
fseek(file, 0, SEEK_SET);
// 写入倒序后的内容
if (fwrite(buffer, 1, file_size, file) != file_size) {
perror("Failed to write to file");
free(buffer);
fclose(file);
exit(EXIT_FAILURE);
}
// 截断文件以移除可能的多余字符,确保文件大小与实际写入内容的大小一致
ftruncate(fileno(file), file_size);
// 关闭文件和释放内存
free(buffer);
fclose(file);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return EXIT_FAILURE;
}
reverse_file_content(argv[1]);
return EXIT_SUCCESS;
}
代码二:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct st {
char c[1024];
struct st* up;
struct st* down;
} *head = NULL, *tp = NULL, *next = NULL;
int main() {
FILE* file_in, *file_out;
char buffer[1024];
file_in = fopen("fileIn", "r");
if (file_in == NULL) {
perror("Failed to open input file");
return EXIT_FAILURE;
}
file_out = fopen("fileOut", "w");
if (file_out == NULL) {
perror("Failed to open output file");
fclose(file_in);
return EXIT_FAILURE;
}
// 读取文件并构建链表
while (fgets(buffer, sizeof(buffer), file_in) != NULL) {
next = (struct st*)malloc(sizeof(struct st));
if (next == NULL) {
perror("Failed to allocate memory");
fclose(file_in);
fclose(file_out);
return EXIT_FAILURE;
}
strncpy(next->c, buffer, sizeof(next->c) - 1);
next->c[sizeof(next->c) - 1] = '\0';
next->down = NULL;
if (head == NULL) {
head = next;
tp = next;
} else {
tp->down = next;
next->up = tp;
tp = next;
}
}
// 倒序写入文件
while (tp != NULL) {
fputs(tp->c, file_out);
tp = tp->up;
}
// 关闭文件指针
fclose(file_in);
fclose(file_out);
// 释放链表内存
tp = head;
while (tp != NULL) {
next = tp->down;
free(tp);
tp = next;
}
return EXIT_SUCCESS;
}
3.编写程序,实现多进程编程,主进程每隔3秒获取当前系统时间写入某文件,子进程每隔2秒访问该文件,读取该文件的内容显示在屏幕上。
解:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
void write_time_to_file(const char *filename) {
FILE *file = fopen(filename, "w");
if (file == NULL) {
perror("Failed to open file");
exit(EXIT_FAILURE);
}
while (1) {
time_t rawtime;
struct tm *timeinfo;
char buffer[80];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", timeinfo);
fprintf(file, "Current time: %s\n", buffer);
fclose(file);
sleep(3); // 每隔3秒写入一次
}
}
void read_time_from_file(const char *filename) {
while (1) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
perror("Failed to open file");
sleep(2); // 等待文件被创建
continue;
}
char buffer[256];
printf("File content:\n");
while (fgets(buffer, sizeof(buffer), file) != NULL) { //fgets读取文件
printf("%s", buffer);
}
fclose(file);
sleep(2); // 每隔2秒读取一次
}
}
int main() {
const char *filename = "time_log.txt";
pid_t pid = fork(); //fork()创建子进程
if (pid < 0) {
perror("Failed to fork");
return EXIT_FAILURE;
} else if (pid == 0) {
// 子进程
read_time_from_file(filename);
} else {
// 主进程
write_time_to_file(filename);
}
return EXIT_SUCCESS;
}
使用gcc编译程序:gcc time_process.c -o time_process