Linux开发工具的使用(二)

Linux开发工具的使用(二)

1.Linux编译器gcc/g++使用

gcc是c语言的编译器,g++是c++的编译器

1.1 背景

程序的翻译分为四个阶段:预处理、编译、汇编、链接,那么这些都是具体做了什么?

.obj文件(.o文件)不可被执行,下面操作进行验证

1.2 验证每一个阶段的效果

gcc [选项] 要编译的文件 [选项] [目标文件]

1.2.1 预处理

gcc/g++ 文件名(作用就是形成可执行文件)

[yinhan@VM-12-12-centos _stu]$ ll
total 4
-rw-rw-r-- 1 yinhan yinhan 185 Jan  6 19:11 myfile.c
[yinhan@VM-12-12-centos _stu]$ gcc myfile.c //gcc + 文件名:生成可执行程序a.out
[yinhan@VM-12-12-centos _stu]$ ll
total 16
-rwxrwxr-x 1 yinhan yinhan 8360 Jan  6 19:11 a.out
-rw-rw-r-- 1 yinhan yinhan  185 Jan  6 19:11 myfile.c
[yinhan@VM-12-12-centos _stu]$ cat myfile.c 
#include <stdio.h>

int main()
{
  printf("hello world\n");
  printf("hello world\n");
  printf("hello world\n");
  printf("hello world\n");
  printf("hello world\n");
  
  return 0;
}
[yinhan@VM-12-12-centos _stu]$ ./a.out 
hello world
hello world
hello world
hello world
hello world
[yinhan@VM-12-12-centos _stu]$ 

-o:制定目标名称, 默认的时候, gcc 编译出来的文件是 a.out==(-o后面永远紧跟着可执行程序的名称)==

gcc/g++ -o 目标文件名名称 源文件名

gcc/g++ 源文件名 -o 目标文件名名称(这两种方式都是可行的)

[yinhan@VM-12-12-centos _stu]$ ll
total 4
-rw-rw-r-- 1 yinhan yinhan 185 Jan  6 19:11 myfile.c
[yinhan@VM-12-12-centos _stu]$ cat myfile.c 
#include <stdio.h>

int main()
{
  printf("hello world\n");
  printf("hello world\n");
  printf("hello world\n");
  printf("hello world\n");
  printf("hello world\n");
  
  return 0;
}
[yinhan@VM-12-12-centos _stu]$ gcc -o myfile myfile.c 
[yinhan@VM-12-12-centos _stu]$ ll
total 16
-rwxrwxr-x 1 yinhan yinhan 8360 Jan  6 19:14 myfile
-rw-rw-r-- 1 yinhan yinhan  185 Jan  6 19:11 myfile.c
[yinhan@VM-12-12-centos _stu]$ ./myfile 
hello world
hello world
hello world
hello world
hello world
[yinhan@VM-12-12-centos _stu]$ gcc myfile.c -o _myfile
[yinhan@VM-12-12-centos _stu]$ ll
total 28
-rwxrwxr-x 1 yinhan yinhan 8360 Jan  6 19:14 myfile
-rwxrwxr-x 1 yinhan yinhan 8360 Jan  6 19:14 _myfile
-rw-rw-r-- 1 yinhan yinhan  185 Jan  6 19:11 myfile.c
[yinhan@VM-12-12-centos _stu]$ ./_myfile 
hello world
hello world
hello world
hello world
hello world
[yinhan@VM-12-12-centos _stu]$ 

gcc/g++ -E 源文件(把预处理后的代码直接显示在显示器上)

gcc/g++ -E 源文件 -o 目标文件名(把预处理的代码放进目标文件中,.i是预处理文件后缀

[yinhan@VM-12-12-centos _stu]$ ll
total 24
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:22 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:24 myfile.i
[yinhan@VM-12-12-centos _stu]$ rm myfile.i
[yinhan@VM-12-12-centos _stu]$ ll
total 4
-rw-rw-r-- 1 yinhan yinhan 520 Jan  6 19:22 myfile.c
[yinhan@VM-12-12-centos _stu]$ gcc -E myfile.c -o myfile.i
[yinhan@VM-12-12-centos _stu]$ 
1.2.2 编译

gcc/g++ -S 源文件(默认生成汇编文件,这个是先对其预处理再编译)

[yinhan@VM-12-12-centos _stu]$ clear
[yinhan@VM-12-12-centos _stu]$ ll
total 24
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
[yinhan@VM-12-12-centos _stu]$ gcc -S myfile.c
[yinhan@VM-12-12-centos _stu]$ ll
total 28
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:36 myfile.s
[yinhan@VM-12-12-centos _stu]$ 

gcc/g++ -S 源文件 -o 目标文件名(这个是对预处理文件直接编译成汇编文件,.s是汇编文件的后缀

[yinhan@VM-12-12-centos _stu]$ ll
total 24
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
[yinhan@VM-12-12-centos _stu]$ gcc -S myfile.i -o myfile.s
[yinhan@VM-12-12-centos _stu]$ ll
total 28
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:38 myfile.s
[yinhan@VM-12-12-centos _stu]$ 
1.2.3 汇编

gcc -c 源文件(先对其预处理再编译再汇编)

[yinhan@VM-12-12-centos _stu]$ ll
total 28
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:42 myfile.s
[yinhan@VM-12-12-centos _stu]$ gcc -c myfile.s
[yinhan@VM-12-12-centos _stu]$ ll
total 32
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rw-rw-r-- 1 yinhan yinhan  2040 Jan  6 19:42 myfile.o
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:42 myfile.s
[yinhan@VM-12-12-centos _stu]$ 

gcc -c 源文件 -o 目标文件名(直接对汇编文件进行汇编)

[yinhan@VM-12-12-centos _stu]$ ll
total 28
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:42 myfile.s
[yinhan@VM-12-12-centos _stu]$ gcc -c myfile.s -o myfile.o
[yinhan@VM-12-12-centos _stu]$ ll
total 32
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rw-rw-r-- 1 yinhan yinhan  2040 Jan  6 19:44 myfile.o
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:42 myfile.s
[yinhan@VM-12-12-centos _stu]$ 

验证.o为后缀的文件是不可被执行的:

[yinhan@VM-12-12-centos _stu]$ ll
total 32
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rw-rw-r-- 1 yinhan yinhan  2041 Jan  6 19:45 myfile.o
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:42 myfile.s
[yinhan@VM-12-12-centos _stu]$ ./myfile.o //是因为没有执行权限导致的吗?
-bash: ./myfile.o: Permission denied
[yinhan@VM-12-12-centos _stu]$ chmod u+x myfile.o //对拥有者提供执行权限
[yinhan@VM-12-12-centos _stu]$ ll
total 32
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rwxrw-r-- 1 yinhan yinhan  2041 Jan  6 19:45 myfile.o
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:42 myfile.s
[yinhan@VM-12-12-centos _stu]$ ./myfile.o 
-bash: ./myfile.o: cannot execute binary file 
[yinhan@VM-12-12-centos _stu]$ 

1.2.4 链接

gcc/g++ .o文件为后缀的文件名

[yinhan@VM-12-12-centos _stu]$ ll
total 32
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rw-rw-r-- 1 yinhan yinhan  2041 Jan  6 19:45 myfile.o
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:42 myfile.s
[yinhan@VM-12-12-centos _stu]$ gcc myfile.o
[yinhan@VM-12-12-centos _stu]$ ll
total 44
-rwxrwxr-x 1 yinhan yinhan  8408 Jan  6 19:47 a.out //生成可执行文件
-rw-rw-r-- 1 yinhan yinhan   520 Jan  6 19:28 myfile.c
-rw-rw-r-- 1 yinhan yinhan 17098 Jan  6 19:28 myfile.i
-rw-rw-r-- 1 yinhan yinhan  2041 Jan  6 19:45 myfile.o
-rw-rw-r-- 1 yinhan yinhan   817 Jan  6 19:42 myfile.s
[yinhan@VM-12-12-centos _stu]$ 
1.2.5 记忆

ESc:每个阶段的选项,对应的也是键盘上的Esc只不过这里的S是大写

.iso:几个阶段的文件后缀

1.3 链接的理解

首先有一个重要的概念是函数库,我们在起初写的printf(“hello world\n”);这个printf库函数是怎么来实现的呢?这个printf库函数并不是我们自己写的,其实:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数printf了。

1.3.1 ldd指令

ldd是list dynamic dependencies的缩写

用法:ldd + 文件名

作用:列出一个程序所需要得动态链接库(动态链接库也可以说是共享链接库,后缀是.so)

[yinhan@VM-12-12-centos _stu]$ which ldd
/usr/bin/ldd
[yinhan@VM-12-12-centos _stu]$ file /usr/bin/ldd
/usr/bin/ldd: Bourne-Again shell script, ASCII text executable

头文件在哪里呢?

这里表明头文件也是放在/usr/inlcude/路径下的文件

链接既然上面说了是和对应的库链接,那么库在哪里呢?

libc.so.6就是库,本质也是文件。

1.3.2 预备

Linux下:静态库:lib(前缀)xxxxx.a(后缀);动态库:lib(前缀)xxxxx.so(后缀)

常识:在安装visual studio2022等IDE或者编译器的时候实际上的工作是帮我们下载安装语言的头文件和库文件。

常识:Linux下的指令都是程序,也都是文件,相当一部分指令都是用C语言写的,既然是程序那么也会使用库,下面图片中就使用到了libc.so.6动态库!怎么证明?

1.3.3 动态库和静态库感性理解到实际理解

动态库感性理解和实际理解结合

从故事讲起来,方便理解:假如你是一个高中生,你这一天的安排就是上午做数学作业和语文作业,下午做完化学作业就休息会去上网吧,晚自习也有课。然后网吧是向学长问的,他说的是在学校南门左拐300米有个暴风网吧。下午了你把化学作业做完了就照着学长给的路线去了暴风网吧,这个点保安老师都不管,然后你就到了暴风网吧,给主管说我想坐在靠窗户旁边的那台电脑,然后玩了两个小时,时间到了然后回到学校,吃了个晚饭继续上晚自习。

为什么要去网吧?因为我自己没有电脑,需要去网吧才有电脑玩游戏。==那么C语言也是一样,为什么需要调用库呢?原因就是没有对应的方法,也没有能力去自己实现,所以就需要库,库中有对应的方法。==参考下图理解程序和库的关系:

上述这一个例子可能不是很明白。这里拿做作业再说,小时候我们可能有过叫别人帮我们写作业的经历,这些事情都给别人完成了,我们自己可以干别的事情,可能我们去学习了其他的感兴趣的课程或者出去看电影或者教室斗地主等等,这样我们的效率提高了。在我们编写下面这样一段程序的时候:

  1 #include <stdio.h>
  2 void swap(int* pa, int* pb)
  3 {
  4   int tmp = *pa;
  5   *pa = *pb;
  6   *pb = tmp;
  7 }
  8 
  9 int main()
 10 {
 11   printf("hello world\n");
 12   int a = 10;
 13   int b = 20;
 14   printf("a = %d, b = %d\n",a ,b);                                                                                                                   
 15   swap(&a, &b);
 16   printf("a = %d, b = %d\n",a ,b);
 17   return 0;
 18 }

通过上面的例子来看这段代码,我们很清楚的是这个printf库函数并不是我们自己写的,其实系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数printf了。

我是怎么知道有网吧的?学长告诉我的。假如说我有个表弟,他是即将进入到我这所高中,然后他问我哪里有网吧,我说的是在学校南门左拐300米有个暴风网吧,然后他还没有上高中就知道了。这里说明的是学长坐的工作就是链接。这里学长就相当于链接器那么什么叫做动态链接呢?这个案例中就是这个暴风网吧的地址你记住了,在你的大脑里程序怎么链接的呢?实际上上述中printf这个库函数在调用的时候,其实是把这个printf在库中的地址拷贝放在可执行程序中

故事还没有完,我的表弟进入到高中的时候,学校接到了学生举报,然后警察局封闭了暴风网吧。那么学校刚来的高一的学生很多都指望着这个暴风网吧,但是现在不行了。本来以前的高一学生很多去这个网吧,现在的这届高一学生就去不成了,那么按以前的来说,这个网吧是很多高中生去的,一般都是四五个人一起去,那么我想说的是网吧是共享的,也可以说是共享网吧。上面我们说的暴风网吧对应的就是动态库,也可以叫做共享库。这个动态库只需要一份就够了,因为是共享的。那么,上述暴风网吧没有了那么动态库就没有了,那么高中学生就上不了网了,也就是所有依赖这个共享库的程序就都不能使用了。如果库被删掉,那么很多依赖于此库的程序就无法运行了,如果库的路径更改了,无法通过/usr/lib/路径来找到动态库,那么依赖库的程序也就无法运行了。

静态库感性理解和实际理解结合

故事还在继续:我上了大学后,我自己高三打暑假工,然后自己买了台电脑,以前是网吧玩,现在可以直接用自己电脑玩了。那么这里自己手上有了电脑就可以不去网吧玩游戏了。 ==这里就是一个静态链接的概念:将库中对应的实现方法直接拷贝自己的程序中,也就是说上述的那段代码如果用静态链接的话,就不用在库中去找对应的printf库函数地址放在程序中,然后通过地址在库中找到对应的方法来完成,而是直接把printf库函数的这个实现方法直接拷贝到程序中,这样来进行链接。==故事还在继续,我上了大学,学校旁边有个黑网吧,然后警察给查封了。但是我也觉得没关系,因为我手中有电脑。换句话说,一旦静态链接成功,即使库没有了,我们不再依赖于库,程序还是正常运行。

总结

库分为动态库和静态库,静态库让编译器对用户程序进行静态链接,动态库让编译器对用户程序进行动态链接。静态库和静态链接:链接的时候,如果是静态链接,找到静态库,拷贝静态库中的所需要的实现功能的代码到自己的可执行程序中。动态库和动态链接:链接的时候,如果是动态链接,找到动态库,拷贝动态库中的所需要的实现功能的代码的地址到自己的可执行程序中。静态链接成功:程序不依赖任何库,可以独立运行。动态链接成功:程序依赖动态库,一旦动态库缺失,程序无法运行。一般的云服务器,默认的只有动态库

优缺点

动态库优点:因为自身拷贝地址,相比静态库节省很大空间(以下有验证)

动态库缺点:程序依赖动态库,一旦动态库缺失,程序无法运行

静态库优点:程序不依赖任何库,可以独立运行

静态库缺点:因为自身拷贝实现功能代码问题,浪费内存/磁盘空间(以下有验证)

安装c语言静态库指令:yum install -y glibc-static(必须root用户)

安装c++语言静态库指令:yum installl -y glibc-static libstdc+±static(必须root用户)

2.Linux项目自动化构建工具-make/Makefile

2.1 概念

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编
译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命
令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一
种在工程方面的编译方法。
make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

2.2 初次见面

2.3 依赖关系和依赖方法

什么是依赖关系?举个生活中例子:我们都有自己的家庭,家庭成员有爸爸和妈妈,那么我是他们的儿子,作为儿子,我们在上学期间,我们的学费、生活费什么的费用都靠的是爸爸来出,我们依赖于自己的爸爸,这就是依赖关系。什么是依赖方法呢?同样,我们在上高中的时候,每个月可能是回到家里找爸爸要钱或者是不回去打电话给爸爸要钱,那么我们不管是怎么样要钱,在爸爸面前要钱的时候都会说:爸,下个月没有生活费给我点生活费。其中这句话中,爸这个字就是依赖关系,然后后面的话就是依赖方法,==只有依赖关系和依赖方法同时存在才能完成程序。==假如我向同学的爸说这句话那就不能完成这个要到生活费这个事情。假如我对我爸只是说了声爸,后半句没有说,那么也是不能完成这件事情的。

同样的在上面图中Makefile文件中写的程序中的myfile:myfile.c这段代码中,myfile就依赖于myfile.c,这段代码下面的gcc -o myfile myfile.c就是依赖关系对应的依赖方法。==明白了依赖关系那么Makefile文件也就是一个围绕依赖关系和依赖方法的一个自动化编译的工具。==下面根据预处理、编译、汇编、链接四个阶段来理解依赖:

2.4 make原理

make是如何工作的,在默认的方式下,也就是我们只输入make命令。

  1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),在上图中,他会找到“myfile”这个文件,并把这个文件作为最终的目标文件。
  3. make解释Makefile文件的底层算法就是用的栈结构

2.5 项目清理

依赖关系中,目标文件对应的依赖文件列表可以是空,验证:

make指令执行的时候默认是从上到下扫描时,默认只会执行第一组目标文件的依赖关系和依赖方法,什么意思?看实例:

.PHONY:总是被执行的。什么意思呢?看下面现象:

上述图中的现象是make多次后提示说myfile以最新的了。那么当我们带上.PHONY呢?

这就是.PHONY这个语法的现象观察后的作用,也就是对目标文件的依赖关系对应的依赖方法总是执行

**上面没做.PHONY处理的,使用make指令后,make提示此文件是最新的了,那么make是怎么知道是最新的呢?**验证:(stat指令是查看文件状态)

其实,make指令检查的是源文件和目标文件的时间,如果源文件时间在目标文件时间前(也就是源文件要旧一些),再次make就会提示此文件是最新的;如果源文件时间在目标文件时间后(也就是源文件要新一些),再次make就会执行相对应的指令。如下:(touch既可以创建文件,也可以更新文件时间)

[yinhan@VM-12-12-centos _stu]$ ll
total 20
-rw-rw-r-- 1 yinhan yinhan   75 Jan  7 20:44 Makefile
-rwxrwxr-x 1 yinhan yinhan 8360 Jan  7 20:44 myfile
-rw-rw-r-- 1 yinhan yinhan   74 Jan  7 20:38 myfile.c
[yinhan@VM-12-12-centos _stu]$ make
make: `myfile' is up to date.
[yinhan@VM-12-12-centos _stu]$ make
make: `myfile' is up to date.
[yinhan@VM-12-12-centos _stu]$ stat myfile
  File: ‘myfile’
  Size: 8360      	Blocks: 24         IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 790070      Links: 1
Access: (0775/-rwxrwxr-x)  Uid: ( 1001/  yinhan)   Gid: ( 1001/  yinhan)
Access: 2023-01-07 20:44:35.505555881 +0800
Modify: 2023-01-07 20:44:35.182552590 +0800
Change: 2023-01-07 20:44:35.182552590 +0800
 Birth: -
[yinhan@VM-12-12-centos _stu]$ stat myfile.c
  File: ‘myfile.c’
  Size: 74        	Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 790069      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/  yinhan)   Gid: ( 1001/  yinhan)
Access: 2023-01-07 20:38:54.831086646 +0800
Modify: 2023-01-07 20:38:54.828086616 +0800
Change: 2023-01-07 20:38:54.828086616 +0800
 Birth: -
[yinhan@VM-12-12-centos _stu]$ touch myfile.c
[yinhan@VM-12-12-centos _stu]$ stat 
stat: missing operand
Try 'stat --help' for more information.
[yinhan@VM-12-12-centos _stu]$ stat myfile.c
  File: ‘myfile.c’
  Size: 74        	Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 790069      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/  yinhan)   Gid: ( 1001/  yinhan)
Access: 2023-01-07 20:53:17.489869168 +0800
Modify: 2023-01-07 20:53:17.415868416 +0800
Change: 2023-01-07 20:53:17.415868416 +0800
 Birth: -
[yinhan@VM-12-12-centos _stu]$ make
gcc -o myfile myfile.c
[yinhan@VM-12-12-centos _stu]$ 

3.sudo配置

首先先看一下没有配置的情况:

[yinhan@VM-12-12-centos _stu]$ sudo ls
[sudo] password for yinhan: 
yinhan is not in the sudoers file.  This incident will be reported.
[yinhan@VM-12-12-centos _stu]$ 

提示:yinhan这个用户没有在sudoers文件中,这种情况将被上报。

3.1 理解sudo

sudo指令使用的时候为什么要输入自己的密码呢?sudo的功能的是以系统管理者的身份执行指令,也就是说,经由 sudo 所执行的指令就好像是 root 亲自执行。既然是这样的功能,为什么不是输入root的密码呢?那么我们sudo一下就是以root身份执行指令,那么这里root不就是没有意义嘛,那为什么需要sudo呢?

首先没有配置sudo,那么sudo+命令是不能执行的,为什么?因为该用户不在信任列表中。这里就可以理解为什么sudo使用时输入自己的密码,原因就在于该用户是值得信任的用户才能使用,不是信任用户是不可使用的,会提示。

3.2 sudo配置

进入到sudoers文件中对其进行更改就OK了。

sudoers文件在哪里?

[yinhan@VM-12-12-centos _stu]$ ls -al /etc/sudoers
-r--r----- 1 root root 4363 Nov  2 10:32 /etc/sudoers //拥有者和所属组都是root
[yinhan@VM-12-12-centos _stu]$ 

怎么配置?

1.使用su命令切换成root用户

2.进入/etc/sudoers并编辑,使用vim /etc/sudoers

3.一直翻到最低层,看到这样的(如图示)

4.退出底行模式下使用wq!指令(因为是系统级配置文件所以修改需要慎重,所以必须强制修改即可)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脚踏车(crush)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值