【Linux操作系统】探秘Linux奥秘:Linux开发工具的解密与实战

🌈个人主页:Sarapines Programmer
🔥 系列专栏:《操作系统实验室》
🔖诗赋清音:柳垂轻絮拂人衣,心随风舞梦飞。 山川湖海皆可涉,勇者征途逐星辉。

目录

🪐1 初识Linux OS

🪐2 Linux开发工具的解密与实战

🌍1. 实验目的

🌍2. 实验准备

🌍3. 实验内容

🌍4. 实验心得

📝总结


🪐1 初识Linux OS

Linux是一种开源的Unix-like操作系统内核,它是基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统。Linux内核最初是由芬兰程序员Linus Torvalds在1991年创建的,之后成为自由软件和开源社区的一个主要项目。

以下是Linux操作系统的一些主要特点和组成部分:

  1. 内核(Kernel): Linux内核是操作系统的核心,它管理系统资源,如处理器、内存、设备驱动程序等。Linus Torvalds最初编写了Linux内核,它是Linux操作系统的基础。

  2. Shell(命令解释器): Linux操作系统使用命令行界面(CLI),用户与系统交互通过Shell。用户可以通过输入命令执行各种任务,管理文件、进程、权限等。常见的Shell包括Bash(Bourne Again SHell)和Zsh。

  3. 文件系统: Linux支持多种文件系统,包括Ext4、XFS、Btrfs等。文件系统负责管理存储设备上的文件和目录,以及文件的权限、所有权等信息。

  4. 用户界面: 虽然Linux以CLI为主,但也支持图形用户界面(GUI)。常见的Linux桌面环境有GNOME、KDE、XFCE等,它们提供了直观的用户体验。

  5. 软件包管理系统: 大多数Linux发行版都有自己的软件包管理系统,用于安装、更新和删除软件。常见的包管理工具有APT(Debian/Ubuntu)、YUM(Red Hat/CentOS)、Pacman(Arch Linux)等。

  6. 网络功能: Linux具有强大的网络功能,支持各种网络协议和服务。它可以作为服务器运行各种网络服务,如Web服务器(Apache、Nginx)、邮件服务器(Postfix、Sendmail)、文件服务器(Samba)等。

  7. 多用户和多任务: Linux是一个多用户系统,多个用户可以同时访问同一台机器。它也是一个多任务系统,可以同时运行多个进程。

  8. 安全性: Linux以安全性而闻名,系统管理员可以设置用户权限、访问控制列表(ACLs)等来确保系统的安全性。

  9. 开源和自由: Linux是开源软件,其源代码可以被任何人查看、修改和分发。大多数Linux发行版是免费提供的,用户可以自由选择、使用和分发。

  10. 发行版(Distribution): 由于Linux内核是开源的,不同的组织和社区创建了各种Linux发行版,例如Ubuntu、Debian、Fedora、CentOS、Arch Linux等。每个发行版都有自己的特点和包管理系统。

总体而言,Linux操作系统是一个强大、灵活且可定制的操作系统,广泛应用于服务器、嵌入式系统、超级计算机等各种领域。


🪐2 Linux开发工具的解密与实战

🌍1. 实验目的

  • 掌握gcc编译方法与使用;
  • 掌握Linux调试器GDB的使用;
  • 实践编译与调试技能,提升对软件开发环境的熟练度。

🌍2. 实验准备

  • 获取 Linux 镜 像文件:下载适用于虚拟机的 Linux 镜像文件,比如 Ubuntu 21.04,从 Ubuntu 官方网站 获取。

  • 安装虚拟化软件:安装 VMware Workstation 或 Virtualbox,两者提供简便的虚拟机管理和配置。

  • 创建 Linux 虚拟机:打开虚拟化软件,按照指引创建新虚拟机。设置内存为 2GB 或更多,其余选项选择 默认值。加载下载好的 Linux 系统 ISO 镜像文件,启动虚拟机完成 Linux 系统安装。


🌍3. 实验内容

1.编译器gcc的使用

(1)编辑一个C语言程序文件 hello.c ,代码如下:

#include <stdio.h>
main()
{char name[20];printf(“Please input your name :”);scanf(“% s”, name);printf(“Welcome % s !\n”, name);return 0;
}

(2)编译文件: gcc -o hello hello.c。

(3)若有错误,修改hello.c的内容,然后再次编译,直至没有错误为止。

解:

(1)编辑一个C语言程序文件 hello.c ,代码如下:

#include <stdio.h>
main()
{char name[20];printf(“Please input your name :”);scanf(“% s”, name);printf(“Welcome % s !\n”, name);return 0;
}

在终端输入vim hello.c,将示例代码输入到hello.c结果显示如下:

退出保存,文件夹多了hello.c文件夹

(2)编译文件: gcc -o hello hello.c。

(3)若有错误,修改hello.c的内容,然后再次编译,直至没有错误为止。

在终端输入gcc -o hello hello.c结果显示报错如下所示:

回到源码hello.c,我们根据报错信息分段分析。

第一段:

hello.c:2:1: warning: return type defaults to ‘int’ [-Wimplicit-int]2 | main()| ^~~~
hello.c: In function ‘main’:
hello.c:5:10: error: stray ‘\342’ in program5 |   printf(���Please input your name:”);|          ^
hello.c:5:11: error: stray ‘\200’ in program5 |   printf(���Please input your name:”);|           ^
hello.c:5:12: error: stray ‘\234’ in program5 |   printf(��Please input your name:”);|            ^
hello.c:5:13: error: ‘Please’ undeclared (first use in this function)5 |   printf(“Please input your name:”);|             ^~~~~~
hello.c:5:13: note: each undeclared identifier is reported only once for each function it appears in
hello.c:5:19: error: expected ‘)’ before ‘input’5 |   printf(“Please input your name:”);|                   ^~~~~~|                   )
hello.c:5:36: error: stray ‘\342’ in program5 |   printf(“Please input your name:���);|                                    ^
hello.c:5:37: error: stray ‘\200’ in program5 |   printf(“Please input your name:���);|                                     ^
hello.c:5:38: error: stray ‘\235’ in program5 |   printf(“Please input your name:��);

这一段显示源码的错误提示是因为代码中使用了不可见的特殊字符,导致编译器无法识别。可以很容易发现源码中的printf(“Please input your name:”);的双引号使用的是中文模式输入,故将其改成printf("Please input your name:");

第二段:

hello.c:6:9: error: stray ‘\342’ in program6 |   scanf(���%s”,name);|         ^
hello.c:6:10: error: stray ‘\200’ in program6 |   scanf(���%s”,name);|          ^
hello.c:6:11: error: stray ‘\234’ in program6 |   scanf(��%s”,name);|           ^
hello.c:6:12: error: expected expression before ‘%’ token6 |   scanf(“%s”,name);|            ^
hello.c:6:14: error: stray ‘\342’ in program6 |   scanf(“%s���,name);|              ^
hello.c:6:15: error: stray ‘\200’ in program6 |   scanf(“%s���,name);|               ^
hello.c:6:16: error: stray ‘\235’ in program6 |   scanf(“%s��,name);|                ^

这一段显示源码的错误提示仍然是因为代码中使用了不可见的特殊字符,导致编译器无法识别。可以很容易发现源码中的scanf(“%s”,name);的双引号使用的是中文模式输入,故将其改成scanf("%s",name);

第三段:

hello.c:7:10: error: stray ‘\342’ in program7 |   printf(���Welcome %s!\n”,name);|          ^
hello.c:7:11: error: stray ‘\200’ in program7 |   printf(���Welcome %s!\n”,name);|           ^
hello.c:7:12: error: stray ‘\234’ in program7 |   printf(��Welcome %s!\n”,name);|            ^
hello.c:7:13: error: ‘Welcome’ undeclared (first use in this function)7 |   printf(“Welcome %s!\n”,name);|             ^~~~~~~
hello.c:7:22: error: ‘s’ undeclared (first use in this function)7 |   printf(“Welcome %s!\n”,name);|                      ^
hello.c:7:23: error: expected ‘)’ before ‘!’ token7 |   printf(“Welcome %s!\n”,name);|                       ^|                       )
hello.c:7:24: error: stray ‘\’ in program7 |   printf(“Welcome %s!\n”,name);|                        ^
hello.c:7:26: error: stray ‘\342’ in program7 |   printf(“Welcome %s!\n���,name);|                          ^
hello.c:7:27: error: stray ‘\200’ in program7 |   printf(“Welcome %s!\n���,name);|                           ^
hello.c:7:28: error: stray ‘\235’ in program7 |   printf(“Welcome %s!\n��,name);

这一段显示源码的错误提示仍然是因为代码中使用了不可见的特殊字符,导致编译器无法识别。可以很容易发现源码中的printf(“Welcome %s!\n”,name);的双引号使用的是中文模式输入,故将其改成printf("Welcome %s!\n",name);

此时改后的代码为:

此时进行编译报错如下:

提示错误是由于没有定义main()的类型,故将main函数前加上int,最终修改版代码如下:

再次进行编译结果显示通过如下:

      

输入./hello运行结果如下:

  

2.使用GDB 调试程序BUG(教材12.7节)

(1)使用文本编辑器输入以下代码greet.c。程序试图倒序输出main 函数中定义的字符串,但结果没有显示。

#include <stdio.h>
int display1(char *string);
int display2(char *string);
main()
{char string[] = “Welcome to 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);
}

(2)使用gcc –g 的选项编译这段代码,运行生成的可执行文件,观察运行结果。

(3)使用gdb 调试程序,通过设置断点、单步跟踪,一步步找出错误所在。(调试过程需截图)

(4)纠正错误,更改源程序并得到正确的结果。

解:

在终端输入vim greet.c,输入以上示例为:

输入gcc -o greet greet.c进行编译结果如下:

    

回到源码greet.c,我们根据报错信息分段分析。

第一段:

greet.c:4:1: warning: return type defaults to ‘int’ [-Wimplicit-int]4 | main()| ^~~~

这里错误提示为main()函数无类型,故在main()前加上int。

第二段:

greet.c: In function ‘main’:
greet.c:6:17: error: stray ‘\342’ in program6 | char string[] = ���Welcome to Linux!”;|                 ^
greet.c:6:18: error: stray ‘\200’ in program6 | char string[] = ���Welcome to Linux!”;|                  ^
greet.c:6:19: error: stray ‘\234’ in program6 | char string[] = ��Welcome to Linux!”;|                   ^
greet.c:6:20: error: ‘Welcome’ undeclared (first use in this function)6 | char string[] = “Welcome to Linux!”;|                    ^~~~~~~
greet.c:6:20: note: each undeclared identifier is reported only once for each function it appears in
greet.c:6:28: error: expected ‘,’ or ‘;’ before ‘to’6 | char string[] = “Welcome to Linux!”;|                            ^~
greet.c:6:37: error: stray ‘\342’ in program6 | char string[] = “Welcome to Linux!���;|                                     ^
greet.c:6:38: error: stray ‘\200’ in program6 | char string[] = “Welcome to Linux!���;|                                      ^
greet.c:6:39: error: stray ‘\235’ in program6 | char string[] = “Welcome to Linux!��;|   

这里错误提示为main()函数内的引号输入为中文模式下输入,需更改为英文状态。根据源码可以很容易发现其他的引号也均需要修改。

第三段:

greet.c: In function ‘display2’:
greet.c:20:8: warning: implicit declaration of function ‘strlen’ [-Wimplicit-function-declaration]20 | size = strlen(string1);|        ^~~~~~
greet.c:20:8: warning: incompatible implicit declaration of built-in function ‘strlen’
greet.c:2:1: note: include ‘<string.h>’ or provide a declaration of ‘strlen’1 | #include <stdio.h>+++ |+#include <string.h>2 | int display1(char *string);
greet.c:21:19: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]21 | string2 = (char *)malloc(size + 1);|                   ^~~~~~
greet.c:21:19: warning: incompatible implicit declaration of built-in function ‘malloc’
greet.c:2:1: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’1 | #include <stdio.h>+++ |+#include <stdlib.h>2 | int display1(char *string);
greet.c:26:17: error: empty character constant26 | string2[size+1]='';

这个错误提示包含了三个问题:

  1. 隐式声明函数strlen/malloc的警告:可以通过在代码中添加#include <string.h>#include <stdlib.h>解决。
  2. 不兼容的隐式声明函数警告:这个问题是因为编译器默认隐式声明了strlen和malloc函数,但是实际上这些函数需要在头文件中声明。通过添加上述的头文件可以解决这个警告。
  3. 空字符常量错误:这个问题是因为在代码中有一个空的字符常量'',这是无效的。如果想要将一个字符数组的最后一个元素设为空字符,应该使用单引号括起来的空格字符,即' '。可以将代码中的空字符常量替换为' '来解决这个问题。

修改源码如下:

  

输入gcc -g test.c -o test进行编译结果如下:

输入./ greet

在23行(for循环处)设置断点:b 24;在29行(printf函数处)设置断点:b 29。此时输入info b查看断点设置情况。

    

输入r运行代码,也可输入n单步运行代码,继续单步运行代码数次,并使用命令查看,发现string2[size-1]的值正确。

继续程序的运行:c

在程序中,第24行代码为:string2[size-i] = string1[i];,这个语句是将字符串string1中的每个字符倒序复制到另一个字符串string2中。但是,在循环中,i的取值范围是从0到size-1,因此在第一次循环中,string2[size-i]实际上是string2[size-0],即string2的最后一个字符,而不是第一个字符。这会导致第一个字符无法被正确赋值。 为了解决这个问题,可以将循环的范围修改为从0到size。这样,在第一次循环中,string2[size-i]就会被正确地赋值为string1中的第一个字符,而不是最后一个字符。修改后的代码如下所示

重新进行编译,结果显示通过。

   


🌍4. 实验心得

  1. 编码注意事项: 在实验中,我学到了在编写代码时需要格外注意当前输入模式,避免在中文输入模式下输入英文符号。这是因为中文输入模式会导致符号被输入法转换,不直接对应ASCII码表中的字符。这种小细节的注意可以避免在后续编译和调试过程中因为字符转换引起的问题,确保代码的准确性和可靠性。

  2. 编译器选项的灵活运用: 通过使用gcc编译器,我掌握了如何通过命令行参数指定编译选项。具体而言,我了解到-Wall选项可开启所有警告信息,有助于发现潜在的错误和问题。同时,使用-g选项能够在编译时生成调试信息,提供更全面的调试支持。这种对编译选项的灵活运用不仅有助于提前发现潜在问题,也为后续的调试工作提供了更充分的信息支持。

  3. 高效调试技巧的应用: 通过实验,我学会了在Linux环境下使用GDB调试器进行代码调试的基本技巧。这包括使用break设置断点、run运行程序以及print打印变量值等命令。这些简洁而强大的调试命令使得在代码调试过程中能够更高效地定位和修复问题,提高了开发效率。通过掌握这些调试技巧,我能够更自信地处理代码中的错误和异常,确保程序的稳定性和可靠性。


📝总结

Linux操作系统的领域就像一片未被勘探的信息大海,引领你勇敢踏入开源系统的神秘领域。这是一场独特的学习冒险,从基本概念到系统架构,逐步揭示更深层次的操作系统原理、命令行工具和高级系统管理的奥秘。

渴望挑战Linux操作系统的学习路径和掌握系统管理技术?不妨点击下方链接,一同探讨更多Linux操作系统的奇迹吧。我们推出了引领趋势的💻 Linux专栏:《探秘Linux | 操作系统解密》,旨在深度探索Linux的实际应用和创新。🌐🔍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/591156.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx解决跨域问题过程

学习Nginx解决跨域问题 结果 server {listen 22222;server_name localhost;location / {if ($request_method OPTIONS) {add_header Access-Control-Allow-Origin http://localhost:8080;add_header Access-Control-Allow-Headers *;add_header Access-Control-Allo…

redis 从0到1完整学习 (十四):RedisObject 之 ZSet 类型

文章目录 1. 引言2. redis 源码下载3. redisObject 管理 ZSet 类型的数据结构4. 参考 1. 引言 前情提要&#xff1a; 《redis 从0到1完整学习 &#xff08;一&#xff09;&#xff1a;安装&初识 redis》 《redis 从0到1完整学习 &#xff08;二&#xff09;&#xff1a;re…

学习记录——BiFormer

BiFormer Vision Transformer with Bi-Level Routing Attention BiFormer:具有双电平路由注意的视觉变压器 摘要作为视觉转换器的核心组成部分,注意力是捕捉长期依赖关系的有力工具。然而,这样的能力是有代价的:当计算跨所有空间位置的成对令牌交互时,它会产生巨大的计算负…

如何理解图卷积网络GCN

文章目录 基本概念度矩阵&#xff08;degree&#xff09;邻接矩阵&#xff08;Adjacency&#xff09; 理解GCN两层GCN网络层数设置 搭建GCN网络定义GCN层定义GCN网络 基本概念 图的一些基本知识&#xff1a;图&#xff0c;邻居&#xff0c;度矩阵&#xff0c;邻接矩阵 度矩阵…

【力扣100】22.括号生成 || 为什么搜索几乎都是用深度优先遍历?

添加链接描述 class Solution:def generateParenthesis(self, n: int) -> List[str]:# 思路是根据左右括号剩余数量进行生成# 剩余左括号小于剩余右括号时&#xff0c;可以加左或者加右# 剩余左括号大于剩余右括号时&#xff0c;舍弃def backtrack(cur,left,right,res):if …

.NET DevOps 接入指南 | 1. GitLab 安装

引言 容器、DevOps和微服务被称为驱动云原生快速发展的三架马车。而DevOps是其中非常重要的一环&#xff0c;DevOps 是由Developers&#xff08;Dev&#xff09;和Operations&#xff08;Ops&#xff09;两个单词简称组成&#xff0c;中文直译就是“开发运维一体化”。 DevOps…

Spring-AOP综述

文章迁移自语雀。 今天下雪了, 完成了spring aop的应用学习, 学到了以前很多忽略的知识点,也写完了各种试验. 今天给程程分享了很多了随州下雪的场景,写了一二三, ♡程程, i miss u 等字体,在雪地上写给程程看, 还拍摄了照片和视频给她, 上午的时候,还做了一个雪人, 哈哈哈, 她…

zlib.decompressFile报错 【Bug已解决-鸿蒙开发】

文章目录 项目场景:问题描述原因分析:解决方案:方案1方案2此Bug解决方案总结寄语项目场景: 最近也是遇到了这个问题,看到网上也有人在询问这个问题,本文总结了自己和其他人的解决经验,解决了zlib.decompressFile报错 的问题。 问题: zlib.decompressFile报错,怎么解…

Find My帽子|苹果Find My技术与帽子结合,智能防丢,全球定位

帽子是戴在头部的服饰&#xff0c;多数可以覆盖头的整个顶部。主要用于保护头部&#xff0c;部分帽子会有突出的边缘&#xff0c;可以遮盖阳光。帽子亦可作打扮之用&#xff0c;也可以用来保护发型、遮盖秃头。可不同种类&#xff0c;例如贝雷帽、鸭舌帽等等。戴帽子在不同的地…

Java 8 中的 Stream 轻松遍历树形结构!

可能平常会遇到一些需求&#xff0c;比如构建菜单&#xff0c;构建树形结构&#xff0c;数据库一般就使用父id来表示&#xff0c;为了降低数据库的查询压力&#xff0c;我们可以使用Java8中的Stream流一次性把数据查出来&#xff0c;然后通过流式处理&#xff0c;我们一起来看看…

Cypress安装与使用教程(3)—— 软测大玩家

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…

SQL常见面试题

今天刷了一遍牛客里的必知必会题&#xff0c;一共50道题&#xff0c;大部分都比较基础&#xff0c;下面汇总一下易错题。 SQL81 顾客登录名 本题几个关键点&#xff1a; 登录名是其名称和所在城市的组合&#xff0c;因此需要使用substring()和concat()截取和拼接字段。得到登…

FL Studio 21最新版本for mac 21.2.2.3740中文解锁版2024最新图文安装教程

FL Studio 21最新版本for mac 21.2.0.3740中文解锁版是最新强大的音乐制作工具。它可以与所有类型的音乐一起创作出令人惊叹的音乐。它提供了一个非常简单且用户友好的集成开发环境&#xff08;IDE&#xff09;来工作。这个完整的音乐工作站是由比利时公司 Image-Line 开发的。…

不知道怎么使用IDEA,一篇文章带你快速上手

前言 IDEA 是由 JetBrains 公司开发的软件产品&#xff0c;全称为 IntelliJ IDEA&#xff0c;一个 Java 语言的集成开发环境。它 —— 在业界被公认为是最好的 Java 开发工具之一&#xff0c;尤其在智能代码助手、代码自动提示、重构、J2EE 支持、Ant、JUnit、CVS 整合、代码审…

经典目标检测YOLO系列(一)复现YOLOV1(3)正样本的匹配及损失函数的实现

经典目标检测YOLO系列(一)复现YOLOV1(3)正样本的匹配及损失函数的实现 之前&#xff0c;我们依据《YOLO目标检测》(ISBN:9787115627094)一书&#xff0c;提出了新的YOLOV1架构&#xff0c;并解决前向推理过程中的两个问题&#xff0c;继续按照此书进行YOLOV1的复现。 经典目标…

5个用于构建Web应用程序的Go Web框架

探索高效Web开发的顶级Go框架 Go&#xff08;或称为Golang&#xff09;以其简洁性、高效性和出色的标准库而闻名。然而&#xff0c;有几个流行的Go Web框架和库为构建Web应用程序提供了额外的功能。以下是五个最值得注意的Go框架&#xff1a; 1. Gin&#xff1a; Gin是一个高…

Tinker 环境下数据表的用法

如果我们要自己手动创建一个模型文件&#xff0c;最简单的方式是通过 make:model 来创建。 php artisan make:model Article 删除模型文件 rm app/Models/Article.php 创建模型的同时顺便创建数据库迁移 php artisan make:model Article -m Eloquent 表命名约定 在该文件中&am…

SIC产业链简述

同第一代硅半导体产业链类似&#xff0c;SiC产业链也分为以下几个环节&#xff1a; 设备和材料环节&#xff0c;包括晶体生长炉、MOCVD、切割设备、碳粉/硅粉/SiC粉体、石墨件等耗材&#xff1b; SiC衬底合外延环节&#xff0c;包括导SiC晶体生长、衬底晶片、外延片等制造&am…

MyBatis学习一:快速入门

前言 公司要求没办法&#xff0c;前端也要了解一下后端知识&#xff0c;这里记录一下自己的学习 学习教程&#xff1a;黑马mybatis教程全套视频教程&#xff0c;2天Mybatis框架从入门到精通 文档&#xff1a; https://mybatis.net.cn/index.html MyBatis 快速入门&#xf…

Python内置库os和sys的常用方法汇总

更多Python学习内容&#xff1a;ipengtao.com Python是一门强大的编程语言&#xff0c;具有丰富的标准库&#xff0c;其中包括os和sys两个常用模块。os模块用于与操作系统交互&#xff0c;提供了许多文件和目录操作的方法&#xff0c;而sys模块用于与Python解释器进行交互&…