Linux实验报告
中南大学
Linux 系统实验报告
目 目
录
实验一····································3~9
实验二···································10~16
实验三··································17~17
实验一
l Shell 程序设计
[ 实验目的
] ]
理解 Shell 程序的设计方法;熟悉 Shell 程序的编辑、运行、调试方法与过程。
[ 实验内容
] 考勤模拟 Shell 程序设计 用 shell 设计一个考勤模拟程序,实现如下功能选择界面:
1.上班签到 2.下班签出 3.缺勤信息查阅 4.退出 考勤程序运行后,提示用户输入上述功能选择,并验证用户输入的用户名和密码;用户信息保存在 userinfo.dat 中。
如果是上班签到,记录签到信息,如果签到时间大于上午 8 时,则提示用户迟到,并记录该迟到信息到 check.dat。
如果是下班签出,记录签出信息,如果签出时间小于下午 6 时,则提示用户早退,并记录该早退信息到 check.dat。
如果用户选择缺勤信息查询,则将 check.dat 中对应该用户的迟到早退信息查出并显示。
用户选择功能执行完,shell 程序继续回到功能选择界面等待下一个用户进行操作。
一、 实验分析
本实验是 shell 程序设计,主要目的是理解 shell 程序的设计方法以及熟悉 shell 程序的编辑、运行、调试方法与过程。
Shell 是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。实际上 Shell 是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。不仅如此,Shell 有自己的编程语言用于对命令的编辑,它允许用户编写由 shell 命令组成的程序。Shell 编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的 Shell 程序与其他应用程序具有同样的效果。
本实验要求设计一个考情模拟的 shell 程序,按照题目要求,可将整个程序分为五个部分:main 函数以及四个功能函数,及一个功能对应一个函数。
1、上下班签到
将此函数定义为 check_in();根据题目要求,运行程序后首先要求用户输入用户名和密码,当用户名密码正确时才可进入,这就要用到 shell 编程中的变量,shell 中的变量和 C 语言或是 JAVA 中的变量都有所不同,shell 中的变量不需要事先声明,给一个变量赋值实际上就定义了一个变量,并且 shell 程序中的变量是无类型的。
我们定义两个变量 name 和 password,由题目要求,用户名和密码需要由用户输入,因此我们定义的变量应该从键盘获取输入值,使用如下语句:
read name password; 我们在开发程序前应先创建一个文件 userinfo.dat 用于存放用户的用户名和密码,当用户输入用户名和密码后就要判断该用户是否合法。方法为从 userinfo.dat 文件中逐行读取数据,并判断是否与用户输入的用户名相同,当遇到相同的用户名时就表明该用户是合法的,可以退出文件的读取,转入判断该用户输入的密码是否正确。
从文件中逐行读取数据方法:
if test -e /home/poe/userinfo.dat
then
while read u_name u_password
do
if test "$name" = "$u_name"
then
break;
else
continue;
fi
done < /home/poe/userinfo.dat
用户名和密码正确后用户进入系统,系统显示用户签到成功,此时还要判断此时的时间是否大于上午 8 时,则提示用户迟到,并记录该迟到信息到 check.dat。
2、下班签出
将此函数定义为 check_out() ,前面部分和上一个函数 check_in()相同,都为判断用户输入的用户名和密码。不同之处在于记录签出信息,如果签出时间小于下午 6 时,则提示用户早退,并记录该早退信息到 check.dat。
3、缺勤信息查阅
将此函数定义为 look(),首先还是判断该用户输入的用户名和密码是否正确。用户进入系统之后就要打印出该用户的签到信息,将 check.dat 中对应该用户的迟到早退信息查出并显示。
在这一步中,首先还是要从 check.dat 文件中逐行读取数据,不过并不直接打印,而是
要等判断用户名后才能打印。
while read record
do
user=${record%% *};
if test "$user" = "$name"
then
echo "$record";
fi
done < /home/poe/check.dat
其中 user=${record%% *};语句表示截取 record 字符串从左边起第一个空格前的字符串,也就是用户名,然后检查和该用户的用户名是否匹配,若匹配则打印否则读取下一条。
二、 实验源码
#! /bin/bash function show(){
echo "-----------------Welcome to Attandance System--------------------";
echo "-----------------
1.check in
--------------------";
echo "-----------------
2.check out
--------------------";
echo "-----------------
3.late
--------------------";
echo "-----------------
4.exit
--------------------";
echo "Please input your choice:"; }
function check_in(){
echo "Please input your name and password:";
read name password;
if test -e /home/poe/userinfo.dat
then
while read u_name u_password
do
if test "$name" = "$u_name"
then
break;
else
continue;
fi
done < /home/poe/userinfo.dat
if test "$name" != "$u_name"
then
echo "Sorry,your name is wrong!";
elif test "$password" != "$u_password"
then
echo "Sorry,your password is wrong!";
else
echo "Congratulation! You are checked in at `date`";
if test `date +%H` -gt 8
then
echo "You are late!";
echo "$name Checked in at "+`date`+".Late!">> check.dat;
fi
fi
else
echo "There is no this file";
fi }
function check_out(){
echo "Please input your name and password:";
read name password;
if test -e /home/poe/userinfo.dat
then
while read u_name u_password
do
if test "$name" = "$u_name"
then
break;
else
continue;
fi
done < /home/poe/userinfo.dat
if test "$name" != "$u_name"
then
echo "Sorry,your name is wrong!";
elif test "$password" != "$u_password"
then
echo "Sorry,your password is wrong!";
else
echo "Congratulation! You are checked out at "+`date`;
if test `date +%H` -lt 18
then
echo "You are early to leave!";
echo "$name Checked out at "+`date`+".Early!">>check.dat;
fi
fi
else
echo "There is no this file";
fi }
function look(){
echo "Please input your name and password:";
read name password;
if test -e /home/poe/userinfo.dat
then
while read u_name u_password
do
if test "$name" = "$u_name"
then
break;
else
continue;
fi
done < /home/poe/userinfo.dat
if test "$name" != "$u_name"
then
echo "Sorry,your name is wrong!";
elif test "$password" != "$u_password"
then
echo "Sorry,your password is wrong!";
else
while read record
do
user=${record%% *};
if test "$user" = "$name"
then
echo "$record";
fi
done < /home/poe/check.dat
fi
else
echo "There is no this file";
fi }
function main(){
clear;
show;
read choice;
case $choice in
1) check_in;;
2) check_out;;
3) look;;
4) exit;;
*) echo "Please input 1~4";;
esac
}
main;
三、 实验步骤及截图
进入终端,输入./attand.sh
实验 2
Linux 高级程序设计- - 进程通信
1 、实验目的
(1)了解 Linux 操作系统下应用程序开发流程 (2)掌握 GNU 工具链的使用
(3)了解 Linux 高级编程技巧(例如 IPC 机制、系统调用等)
2 、实验内容 (1)
编写一个简单的 C 语言程序,编写 Makefile 文件。了解编译过程,并用 gdb 进行调试。
(2)
以下任选其一:
1. 编写一个多进程通信程序,采用 Message Queue 或 shared Memory 或者Pipeline File 机制进行通信 2. 编写一个实现读者-写者问题的程序,用信号量机制
备注:读者-写者问题
设有一组共享数据 DB 和两组并发进程,一组进程只对此组数据执行读操作,另一组进程可对此组数据执行写操作(同时也可以执行读操作)。将前面一组进程称为读者,后一组进程称为写者。为了保证共享数据的完整性,要求:
(1)多个读者的操作可以同时进行
(2)多个写者的操作不可同时进行
(3)任何读者与写者的操作不可同时进行
3 、实验要求 (1)
写出源程序,并编译运行 (2)
详细记录程序调试及运行结果
一、Makefile 思路分析 在本实验中编写输入学生人数及分数,计算学生的总成绩以及平均成绩的程序,源程序如下:
/*main.c*/ #include <stdio.h> #include "chengji.h" int main(){
int n,i;
float sum,avg;
printf("please input the number ofstudents:");
scanf("%d",&n);
float score[n];
for(i=0;i<n;i++){
printf("please input the score of student[%d]",i);
scanf("%d",&score[i]);
}
sum=fun_sum(score,n);
avg=fun_avg(score,n);
printf("the sum is %f,the avg is %f",sum,avg);
}
/*chengji.h*/ float fun_sum(float array[],int n); float fun_avg(float array[],int n);
/*fun_sum.c*/ float fun_sum(float array[],int n){
float sum=0.0;
for(int i=0;i<n;i++)
sum+=array[i];
return sum; }
/*fun_avg.c*/ float fun_avg(float array[],int n){
float avg=0.0;
for(int i=0;i<n;i++)
avg+=array[i];
avg/=n;
return avg; }
Makefile 文件如下:
main:main.o fun_sum.o fun_avg.o
gcc main.o fun_sum.o fun_avg.o -o main main.o:main.c chengji.h
gcc main.c -c fun_sum.o:fun_sum.c
gcc fun_sum.c -c fun_avg.o:fun_avg.c
gcc fun_avg.c -c
运行结果如下:
二、 读者- 写者思路分析 读写信号量的特点是:
1. 同一时刻最多有一个写者(writer)获得锁; 2. 同一时刻可以有多个读者(reader)获得锁; 3. 同一时刻写者和读者不能同时获得锁; 由于读者可以同时获得锁,因此提高了系统的并发程度,进而提高了系统的性能。
源程序如下:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
// 定义数据类
class data
{
public:
data(int i, float f):
I(i), F(f)
{}
int I;
float F;
};
// 读者写者读写的内容
data *p_data = NULL;
pthread_rwlock_t lock;
// 写者数目
const int WRITER_NUMBER = 2;
void *reader(void *arg);
void *writer(void *arg);
int main(int argc, char **argv)
{
pthread_t reader_tid;
pthread_t writer_tid[WRITER_NUMBER];
pthread_create(&reader_tid, NULL, reader, NULL);
for (int i = 0; i < WRITER_NUMBER; ++i)
{
pthread_create(&writer_tid[i], NULL, writer, (void *)i);
}
sleep(1);
return 0;
}
void *reader(void *arg)
{
long id = (long)arg;
pthread_detach(pthread_self());
while (true)
{
pthread_rwlock_rdlock(&lock);
printf("reader %d is reading the data; ", id);
if (p_data == NULL)
{
printf("the data is NULL\n");
}
else
{
printf("the data is (%d, %f)\n", p_data->I, p_data->F);
}
pthread_rwlock_unlock(&lock);
}
return (void *)0;
}
void *writer(void *arg)
{
pthread_detach(pthread_self());
while (true)
{
pthread_rwlock_wrlock(&lock);
printf("writer is writing the data; ");
if (p_data == NULL)
{
p_data = new data(1, 1.1f);
printf("writer create the data (%d, %f)\n", p_data->I, p_data->F);
}
else
{
delete p_data;
p_data = NULL;
printf("writer free the data\n");
}
pthread_rwlock_unlock(&lock);
}
return (void *)0;
}
实验三:
c Proc 文件系统
【实验目的】本实验作业将通过 Proc 文件系统观察整个系统的一些重要特征,并要求编写一个程序,利用 Proc 文件系统获得和修改系统的各种配置参数。
【实验内容】
1、以超级用户的身份登录 Linux 系统,并进入/proc 目录,输入 ls 命令,查看该目录下的内容,同时查看每个文件的读、写权限。并 回答下列问题:
CPU 的类型和型号
1
Intel(R) Core(TM) i3-2350M CPU @ 2.30GHz
所使用的 Linux 的版本
Linux ubuntu 4.8.0-52-generic #55~16.04.1-Ubuntu SMP Fri Apr 28 14:36:29 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
从启动到当前时刻经过的时间
当前内存状态
2、 、 编写一个程序,用来获得内核参数(任意的参数均可)
3 、编写一个程序,用来修改内核参数(任意的参数均可)