以下是关于嵌入式操作系统(Linux篇)的实验汇总,大概率都是会考的
特别是shell程序和文件IO的操作
嵌入式操作系统实验小结—涉及期末大题
(一)Linux操作系统的使用实验
1、认识Linux操作系统的目录结构
请进入自己电脑Linux操作系统的目录,绘制出系统的目录结构树形图,并把第一层目录的作用与功能写出来(至少写6个目录的常用功能)。
图就自己画了哦很简单的。
eg:
/bin 存放二进制程序
/boot 存放内核和启动所需的文件
/dev 存放设备文件
/etc 存放系统配置文件
/home 用户根目录
/lib 存放库文件
2、文件与目录相关命令的使用
- 进入/bin目录,并查看该目录下有哪些文件:
cd /bin
ls -l
(2)进入用户主目录,在用户主目录下,新建目录myshare:
cd /home/xxxxxxxx ( cd ~)
mkdir myshare
ls -ld myshare/
(3)用pwd命令查看当前所在的目录
Pwd
(4)新建testfile文件
touch testfile
ls -l
(5)设置该文件的权限模式
chmod 755 testfile
ls -l testfile
(6)把该文件备份到/tmp/myshare目录下,并改名为testfile.bak。
cp testfile myshare/testfile.bak
ls -l myshare/
(7)在/root目录下为该文件创建1个符号连接(若无权限,可使用root账号操作)。
ln -s /tmp/testfile /root/testfile.ln
ls -l /root/testfile.ln
(8)删除testfile.bak文件
rm myshare/testfile.bak
ls -l myshare 通过该命令检查是否删除成功。
3、用户与系统相关命令的使用
(1)将普通用户模式转变为超级用户
su
然后输入超级用户密码。
从超级用户切回到普通用户
su xxxxxx
(2)通过ps命令查看进程列表
ps -ef
(-e 显示所有进程 -f全格式)
4. 压缩备份命令的使用
(1)把/tmp目录打包成tmp.tar,放到/root目录下
tar -cf /root/tmp.tar /tmp/*
(2)把/tmp目录压缩打包成tmp.tar.gz,放到/root目录下:
tar -zcvf /root/tmp.tar.gz /tmp/*
(3)比较tmp.tar和tmp.tar.gz的大小:ls -l /root/tmp.tar /root/tmp.tar.gz
(4)解压tmp.tar.gz的内容到/tmp/myshare目录:
tar zxvf /root/tmp.tar.gz -C /tmp/myshare/
(5)把/tmp目录下每个文件压缩成.gz格式:gzip *
(6)详细列出每个.gz压缩文件的信息,不解压:gzip –l *
把每个.gz压缩文件解压,并列出详细信息:gzip –dv *
(二)Vim编辑器的使用实验
先确保系统以安装好Vim编辑器(安装方法:sudo apt-get install vim),再启动Vim进入编辑器。
Vi编辑器有基本的三种模式:命令模式、编辑模式、底行模式。学会在三种模式之间的自由切换,以及三种模式下的常用命令的使用。参考教材中命令行模式和底行模式下的常见功能键完成如下操作练习。
1、准备
Ø 在“/tmp”目录下建一个名为“ViTest”的目录。Mkdir /tmp/ViTest
Ø 进入“ViTest”目录。cd /tmp/ViTest
2 基本功能使用实验
Vim编辑的基本功能是:启动编辑器--进入编辑模式--编辑文本—退出编辑模式--保存并退出编辑器。
请在/tmp/ViTest完成如上Vi编辑器的常规流程操作实验,并写出每一个步骤的操作命令方法是什么?
实验结果:
(1)启动编辑器:在终端输入`vim /tmp/ViTest`,回车。这将打开Vim编辑器并创建一个名为ViTest的文件,如果文件已经存在,则会打开该文件。
(2)进入编辑模式:在Vim编辑器中,按`i`键进入插入模式,这时可以开始编辑文本。
(3)编辑文本:在插入模式下,可以直接输入文本进行编辑。
(4)退出编辑模式:完成编辑后,按`Esc`键退出插入模式,返回到命令模式。
(5)保存并退出编辑器:在命令模式下,输入`:wq`,然后按回车。这将保存对文件的更改并退出Vim编辑器。
3 其他功能操作实验
Ø 进入ViTest目录,将文件“/etc/profile”复制到“/ViTest”目录下。cp /etc/profile ./
再使用chmod命令更改ViTest目录下profile文件的权限为777。
Chmod 777 profile
Ø 使用Vi 打开“Vi”目录下的profile。 vi profile(请doublecheck是否是编辑的Vi目录下的profile,一定不要编辑etc目录下的profile)
请根据课堂讲述内容检查确认当前Vi编辑器属于什么模式?再按步骤完成如下命令的使用操作。
Vi编辑器属于命令模式
- Ø 设定行号(:set nu),指出“判断profile.d文件(if [ -d /etc/profile.d ])是否存在”判断语句的行号。
- Ø 将光标移到该行。如:19<enter>或20G(注意G要大写)
- Ø 复制该行内容。yy
- Ø 将光标移到最后一行行首。G
- Ø 粘贴复制行的内容。p
- Ø 撤销上一步的动作。u
- Ø 将光标移动到行尾。$或End
- Ø 光标移到21行。21G
- Ø 删除该行。dd
- Ø 存盘但不退出。:w(底行模式)——注意检查底部的英文提示信息
- Ø 将光标移到首行。1G
- Ø 插入模式下输入“Hello,this is Vi world!”。按i 键并输入“Hello,this is Vi world!”(插
- 入模式)
- Ø 返回命令行模式。Esc
- Ø 向下查找字符串“bashrc”。 /bashrc(命令行模式)
- Ø 再向上查找字符串“etc”。 ?etc
- Ø 强制退出Vi,不存盘。:q!(底行模式)
(三)Shell脚本编程实验
1、Shell命令脚本编写实验:编写一个shell程序,实现:在/tmp目录下,新建一个目录,目录名称为【当前用户名+TEST】,然后再将/etc/profile文件拷贝到该目录下。
实验内容3.1实验报告 | |
实验题目 | Shell命令脚本编写实验 |
Shell程序源码 | ///***此处贴上Shell程序源代码 注意:每个Shell脚本的第一条语句请使用下面这条语句: echo "This is $LOGNAME's Shell Test Script._RunTime:`date`" #!/bin/bash echo "This is $LOGNAME's Shell Test Script._RunTime:`date`" # 获取当前用户名 USERNAME=$(whoami) # 构建目录名称 DIRNAME="${USERNAME}TEST" # 在/tmp目录下新建目录 mkdir /tmp/$DIRNAME # 检查目录是否创建成功 if [ -d "/tmp/$DIRNAME" ]; then echo "目录 /tmp/$DIRNAME 创建成功" # 将/etc/profile文件拷贝到该目录下 cp /etc/profile /tmp/$DIRNAME/ if [ $? -eq 0 ]; then echo "文件 /etc/profile 已成功拷贝到 /tmp/$DIRNAME/" else echo "拷贝文件时出错" fi else echo "目录创建失败" fi |
运行过程及结果截图 | ///***此处贴上S hell程序运行过程及结果截图 |
其他情况说明 |
2、数值计算程序编写实验:编写一个shell程序,实现计算100以内能被3整除的数的个数和这些数的和。(提示:可用数值运算命令expr)
实验内容3.1实验报告 | |
实验题目 | 数值计算程序编写实验 |
Shell程序源码 | ///***此处贴上Shell程序源代码 注意:每个Shell脚本的第一条语句请使用下面这条语句: echo "This is $LOGNAME's Shell Test Script._RunTime:`date`" #!/bin/bash echo "This is $LOGNAME's Shell Test Script._RunTime:`date`" count=0 sum=0 for ((num=1; num<=100; num++)) do if (( num % 3 == 0)) then count=$((count + 1)) sum=$((sum + num)) fi done echo "100以内能被3整除的数的个数为: $count" echo "这些数的和为: $sum |
运行过程及结果截图 | ///***此处贴上Shell程序运行过程及结果截图 |
其他情况说明 |
- 函数编程实验:编写一个shell程序,先设计一个函数NumberReverse,用于实现对输入的一串数字取反序,如:输入1234,则打印4321。然后在主函数中实现循环等待用户输入一串数字,再调用当用户输入q时,程序退出。
实验内容3.1实验报告 | |
实验题目 | 函数编程实验 |
Shell程序源码 | ///***此处贴上Shell程序源代码 注意:每个Shell脚本的第一条语句请使用下面这条语句: echo "This is $LOGNAME's Shell Test Script._RunTime:`date`" #!/bin/bash echo "This is $LOGNAME's Shell Test Script._RunTime:`date`" NumberReverse() { local reversed="" local -n num_str=$1 for (( i=${#num_str}-1; i>=0; i-- )) do reversed="${reversed}${num_str:$i:1}" done echo "$reversed" } while true; do read -p "请输入一串数字(输入q退出): " input if [ "$input" == "q" ]; then echo "程序已退出。" break fi reversed_number=$(NumberReverse input) echo "反转后的数字是: $reversed_number" done |
运行过程及结果截图 | ///***此处贴上Shell程序运行过程及结果截图 |
其他情况说明 |
(四)GCC 编译器的使用
参考教材中gcc的命令和编译选项,自行构造实验,测试总体选项、警告和出错选项以及优化选项的编译效果。请自由选择3个编译选项进行对比试验,并描述该编译选项的效果是什么。
- -Wall(启动所有警告)【这个应该触发a未初始化的信息】
- gcc -Wall hello.c -o hello
- -Werror(将警告视为错误)
- gcc -Werror hello.c -o hello
- -O2(优化等级为2)
- gcc -O2 hello.c -o hello
(五)GDB 基本命令的使用
使用Vim 编辑源程序,在终端中输入vi gdbtest.c,输入如下源代码,
编辑完成后存盘。此代码的功能为输出倒序main 函数中string[]数组中定义的字符串,但结果没有输出显示,现通过gdb调试的方式来解决程序中存在的问题。程序源代码如下:
#include <stdio.h>
int display1 (char *string)
int display2 (char *string1)
int main ()
{
char string[] = "Embedded Linux";
display1 (string);
display2 (string);
}
int display1 (char *string)
{
printf ("The original string is %s \n", string);
}
int display2 (char *string1)
{
char *string2;
int size,i;
size = strlen (string1);
string2 = (char *) malloc (size + 1);
for (i = 0; i < size; i++)
string2[size - i] = string1[i];
string2[size+1] = ' ';
printf("The string afterward is %s\n",string2);
}
(1)用gcc 编译:gcc gdbtest.c -o gdbtest
编译是否会报错?如报错,请根据报错信息分析错误原因,修改编译错误,并把修改方法在此描述。修改编译通过后再进行后续实验。
(2)运行gdbtest:./ gdbtest,分析程序运行的输出结果是?
请分析程序输出结果,分析其存在的问题。
(3)启动Gdb 调试:gdb gdbtest
输入gdb命令l,查看源代码:观察是否可以正常查看到源代码?如不能请分析原因是什么并回答。使用q命令,退出gdb。
不可以看到源代码,未加上“-g”选项,这样编译出的可执行文件不会包含调试信息,GDB无法载入该可执行文件
(4)用gcc的-g选项重新编译:gcc -g gdbtest.c -o gdbtest
再次启动gdb调试:gdb gdbtest
输入gdb命令l,查看源代码:
Ø
在20 行(for 循环处)设置断点:b 20
Ø 在23 行(printf 函数处)设置断点:b 23。
Ø 查看断点设置情况:info b
Ø 运行代码:r
Ø 单步运行代码:n
Ø 查看暂停点变量值:p string2[size - i]
查看暂停点变量值:p i
Ø 继续单步运行代码数次,并使用命令查看变量的值,发现string2[size-1]的值正确
Ø 继续程序的运行:c
Ø 程序在printf 前停止运行,此时依次查看string2[0]、string2[1]…,发现string[0]没
有被正确赋值,而后面的复制都是正确的,这时,定位程序第31 行,发现程序运
行结果错误的原因在于“size-1”。由于i 只能增到“size-1”,这样string2[0]就永远
不能被赋值而保持NULL,故输不出任何结果。
Ø 退出gdb:q
Ø 重新编辑gdbtest.c,把其中的“string2[size - i] = string1[i]”改为“string2[size – i - 1] =
string1[i];”即可。
使用Gcc 重新编译,查看运行结果:./ gdbtest
The original string is Embedded Linux
The string afterward is xuniL deddedbmE
这时,输入结果正确。
(六)Make 工程管理器的使用
小结过程:
vi MakeTest.c
写测试代码
vi makefile
写Makefile代码
退出vim
make
./MakeTest.c
(1)编辑源代码,利用文本编辑器vi 创建MakeTest.c 文件,vi MakeTest.c
#include <stdio.h>
int main()
{
printf("Welcome to Test makefile!\n");
return 1;
}
(2)编写Makefile 文件。
利用文本编辑器创建一个makefile 文件,并将其保存到与MakeTest.c 相同的目录下
CC=gcc
CFLAGS=
all: MakeTest
MakeTest: MakeTest.o
$(CC) $(CFLAGS) MakeTest.o –o MakeTest
MakeTest.o: MakeTest.c
$(CC) $(CFLAGS) –c MakeTest.c –o MakeTest.o
clean:
rm *.o
- 使用Make 编译项目。执行make,查看并记录所生成的文件,对生成可执行程序进行运行,查看运行的结果。
(七)文件IO编程实验
(1)基本IO(非缓冲)操作编程:编写一个基本IO操作的源代码,要求使用到基本IO操作的5个函数:打开、读取、写入、定位和关闭。编译上述源代码并调试通过,最后对运行结果予以分析验证。
open、write、lseek、read、close
(2)标准IO(缓冲)操作编程:编写一个标准IO操作的源代码,要求使用到标准IO操作的5个函数:打开、读取、写入、定位和关闭。编译上述源代码并调试通过,最后对运行结果予以分析验证。
fopen、fwrite、fseek、fread、fclose
注:文件IO编程操作实验中,要实现的具体功能自拟(只要应用到了5个函数即可),提交源代码和对应的运行结果。
补充:(期末大题)
(1)基本IO操作的综合示例:
/****fileio.c***/
#include <unistd.h>
#include<sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(void)
{ int fd, size;
char s[] ="This program is used to show how to use open(), write(), read() function.\nHave fun!\n”;
char buffer[80];
/*以可读写的方式打开一个文件,如果不存在则创建该文件*/
fd = open("temp.log",O_WRONLY|O_CREAT );
if(-1 ==fd)
{printf("Open or create file named \"temp.log\" failed.\n");
return -1;}
write( fd, s, sizeof(s) );/*向该文件中写入一个字符串*/
close( fd );
fd =open("temp.log", O_RDONLY);
if (-1 == fd )
(printf("Open file named \"temp.log\"failed.\n”))return -1;}
/*读取文件内容保存到buffer指定的字符串数组中,返回读取的字符个数
size = read( fd, buffer, sizeof(buffer) );
close( fd );
printf( "%s", buffer );
return 0;
(2)标准IO操作的综合示例:
/****readrec.c***/
#include <stdio.h>
#include <stdlib.h>
struct record {
char name[10];
int age;
};
int main(void)
(
struct record array[2];
FILE *fp = fopen("recfile", "r"); if (fp ==NULL){
perror("Open file recfile”);exit(1);
}
fread(array, sizeof(struct record), 2, fp);
printf("Name1: %s\tAge1: %d\n", array[0].name, array[0].age);
printf("Name2: %s\tAge2: %d\n", array[1].name, array[1].age);
fclose(fp);
return 0;
)
/****writerec.c***/
#include <stdio.h>
#include <stdlib.h>
struct record {char name[10];int age;};
int main(void){
struct record array[2] = {{"Ken", 24), ("Knuth", 28});
FILE *fp = fopen("recfile", "w"); if (fp ==NULL)(
perror("Open file recfile");
exit(1);
fwrite(array, sizeof(struct record), 2, fp); fclose(fp);
return 0;
}