LINUX学习笔记
hostnamectl set-hostname leilei主机名修改主机名
//云服务器给多人应用
adduser zhangsan //新建用户
passwd zhangsan //给用户设置密码
//登入
ssh zhangsan@47.100.18.153
//删除用户
userdel -r zahngsan
//root用户登录
普通用户->root:su 后输入root密码,再【ctrl+D】或exit返回普通用户
su是身份变换,su-是重新登录root
root->普通用户:su 用户名,再【ctrl+D】或exit返回普通用户
sudo 命令:提升命令权限(adduser新建用户无法提权限,系统不信任,需将用户添加到系统白名单)
u为拥有者,g为群组,o为其他
文件的权限修改1:chmod u+w test.txt (给文件test的拥有者添加写的权限:r读w写x运行)
文件的权限修改2:chmod 000 test.txt (运用8进制来代替每个角色的权限:7=111)
在root账号下通过chown和chgrp更改拥有者和组别(chown leilei test.txt)
一键更改角色 chown leilei:leilei test.txt(拥有者和所属组都改成leilei)
普通文件的默认权限为664,目录文件的默认权限为775
原因:有权限掩码umask(默认为0002)凡是在权限掩码中出现的权限不会出出现在最终目录中
最终权限 = 起始权限 & (~umask)umask用于设置文件的起始权限
umask 0001:设置umask为0001
目录文件rwx权限
r:是否允许查看指定目录下的文件内容;
w:是否允许在当前目录下创建、修改、删除文件
x:是否允许用户进入对应的目录文件
一个文件能否被删除,不由这个文件决定,而由这个文件所在的目录决定
可以通过root账号设置共享目录,使所有普通用户都可以读写删
共享目录可以设置粘滞位 t ,使得只允许文件拥有者和root可以删除对应文件
alt+enter:全屏与取消全屏
ls:当前目录下的文件
pwd:当前目录所在位置,/home/lei
mkdir 108_class:创建目录
cd 108_class:进入108_class目录下
touch test.txt:创建txt文件,touch创建普通文件
ls -l:当前目录下文件的详细信息=ll,d开头是文件夹目录,-开头是普通文件
文件 = 文件属性+文件内容
创建文件时以.开头是隐藏文件
ls -a: 展示目录下所有文件(包括隐藏文件)
linux下任何目录中都有.\..
..表示当前路径的上级路径,一个.表示当前路径,帮助用户定位当前目录下的文件
cd .. 回到上级路径
ls -d:显示当前目录的属性,并非目录下的文件属性
ls -F:显示目录下文件的最后一个属性符号
ls *:*表示通配符
cd -:回退到最近一次所在得路径
cd ~:回退到家目录
tree .:以树状的形式展示目录路径(root下安装tree :yum install -y tree)
mkdir -p dd1/dd2/dd3:循环创建文件
rmdir dd3:删除空目录
rm test.txt:删除普通文件,有提示
rm -f test.txt:强制删除,无提示
rm -r dd1:递归删除目录,有提示
rm -rf dd1:强制递归删除目录,无提示
man ls:查看指令手册
echo “hello,linux” > test.txt:将hello,linux文本写入到test文件中,输出重定向
cat test.txt:打印test文件中的内容
cp src dest:可以把src文件拷贝到dest文件中
mv src dest:剪切重命名
ctrl+c:终止当前程序指令
alias 108_cmd = ‘ls -l -i’:把ls -l -i重名为108_cmd; 取消重名alias 108_cmd =' ';
echo后面跟的是字符串,打印的也是字符串
echo "hello" > out.txt:输出重定向到out.txt,第一步清除目标文件内容,第二步输入文件
echo "hello" >> out.txt:追加重定向,重定向不清楚原始文件内容
cat < out.txt:输入重定向,本来从键盘读取,现在从指定文件读
cat 不适合看大文本,适合小文本阅读
more 将大文本自顶向下的打印满屏幕,按enter继续打印,按q退出
more -500 text.txt 打印500行
less:可以按上下键进行上下翻, /999,指定打印
head -n text.txt:提取text的前n行
tail -n text.txt:提取text的后n行
//脚本:生成10000行数据
cnt=1; while [ $cnt -le 10000 ]; do echo "hello Linux"; let cnt++; done > text.txt
//管道
head -1020 text.txt | tail -21 :“ | ”类似于管道文件
=(head -1020 text.txt > tmp.txt
tail -21 tmp.txt)
date +%Y-%m-%d:输出日期年月日,时间是H:M:S
date +%s:输出时间戳
date +%Y-%m-%d_%H:%M:%S -d @1738848945:将时间戳转化为年月日时间
cal 2024:查找2024年得日历
find ~ -name *.txt:查找根目录下所有.txt的文件
which ls:在指令路径下搜索指令文件
whereis:在系统特定的路径之下查找,既可以找到可执行程序,又可以找到手册、安装包之类的文件
grep '999' text.txt :在text文件中找到包含999的内容,行文本过滤工具
grep -v '999' text.txt :在text文件中找到不包含999的内容,-n:排序,-i:忽略大小写
zip -r text.zip text.txt:打包text文件
unzip text.zip:解压text文件
unzip text.zip -d d1:将text文件解压后放到d1目录中
tar czf XXX:将XXX文件打包压缩
tar tzf XXX.tgz:预览
tar xzf XXX.tgz:解压解包
tar xzf XXX.tgz -C ..:解压解包到上级路径
//安装zip
以root方式登录/ su / su -
yum install -y zip unzip
bc :计算器
uname -a:查看计算机体系结构,内核版本
【tab键】命令补全
【ctrl+R】历史命令查找 history查看所有的历史命令列表(Linux默认记录1000条命令)
【ctrl+C】命令取消
【ctrl+D】推出终端
yum list | grep lrzsz:找到lrzsz的软件包名,工具用于windows和linux拖拽上传文件
yum install lrzsz.x86_64:安装软件
yum remove lrzsz.x86_64:卸载软件
yum remove -y lrzsz.x86_64:卸载软件不需要回复
yum怎么知道从哪个服务器下载软件
我怎么知道下载哪些文件呢
ls /etc/yum.repos.d/:查看yum源
yum install -y epel-release:下载扩展源
yum install -y sl:小火车
yum install -y cowsay:
vim编辑器--文本编写,多模式的编辑器:命令模式、插入模式、底行模式
命令->插入:i;回退esc;
命令->底行:shift+";";回退esc; w保存,q退出vim
vim配置
在目录/etc/下面有个名为vimrc的文件,或者在家目录下创建.vimrc
touch .vimrc
vim .vimrc——>set nu:下次打开vim code.c的时候自动加上行号
set showmatch:匹配高亮
在非root账户下配置以下vim配置:
curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh
命令模式:
gg 定位光标到第一行;
shift+g 定位光标到最后一行;
n+shift+g 定位到任意一行;
(n)yy 复制光标所在行;
(n)p 粘贴到光标的下一行;
(n)dd 剪切光标所在行及以下n行
shift+$:定位到该行结尾;
shift+^:定位到该行开头;锚点
w和b:光标实现单词间的移动
h,j,k,l:左下上右 移动
u:撤销
ctrl+r:撤销的撤销
shift+~:大小写
(n)r+x:将光标+之后的字符批量化替换成x
shift+R:对内容进行整体的替换
(n)x:光标之后的字符进行删除
多文件:
进入底行,输入vs test.c,实现多文本编辑;
文件间切换:ctrl + ww
底行模式:
set nu:设置编号
set nonu:
108_2023.6.3
普通用户sudo用不了,因为未将普通用户添加到系统的信任列表里
在root账户下,vim /etc/sudoers
找到100行左右
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
lei ALL=(ALL) ALL
底行模式:wq!退出就可以;
背景知识:gcc code.c -o code
1、预处理:去注释、头文件展开、条件编译、宏替换 gcc -E code.c -o code.i
2、编译(检查语法,生成汇编代码) gcc -S code.c -o code.s
3、汇编(生成机器可识别代码) gcc -c code.s -o code.o 查看 od code.o
code.o->可重定位目标二进制文件,目标文件.obj,需要链接才能执行
4、链接(生成可执行文件或库文件) gcc code.o -o code
将可重定位目标二进制文件和库进行链接形成可执行程序
C/C++头文件地址:/usr/include/
C语言标准库:/usr/lib64/libc.so*
链接的过程需要库,库中提供方法的实现,Linux中.so为动态库,.a为静态库;Windows中.dll动态库,.lib为静态库;
库的命名规则:libname.so
库其实就是把源文件(.c),经过一定的翻译,然后打包,只提供一个文件即可,不用提供太多的源文件,也可以达到隐藏源文件的目的
头文件提供方法的申明+库文件提供方法的实现+代码=可执行程序
ldd code:可以查看code可执行程序所依赖的动态库
在linux中,编译形成可执行程序,默认采用的是动态链接--提供动态库,但是没有动态库,有静态库而且gcc能连接成功
所以形成可执行程序,不一定全是动态库或是静态库,有可能是混合的;
想要静态链接,需要加上-static,如 gcc code.c -o code_static -static,所有的链接要求变成静态链接
C静态库的安装:sudo yum install -y glibc-static
c++静态库的安装:sudo yum install -y libstdc++-static
file code
file code_static
file: 命令用于检测文件类型,通过读取文件头或内容推断其类型,(如可执行文件、文本文件、动态库等)
编译的可执行程序以debug的方式发布:gcc code.c -o code_debug -g
安装g++:sudo yum install gcc-c++
执行程序时,需要加上./code:因为执行程序时需要找到这个程序才行,定位这个二进制文件的位置,找到后加载到内存上去运行
make/Makefile:在源代码的目录中对源代码进行编译形成可执行程序;
make是命令,Makefile是文件;
当make编译后形成可执行程序后,再次make无法成功,如果删除了编译成功的可执行程序或是更改了源文件,那么再次make才有用;
原理是:源文件的最近修改时间比可执行程序的时间要老;
stat code.c
stat可查看源文件和可执行程序的时间:Access\Modify\Change
Access:最近一次被访问的时间; 文件=文件内容+文件属性
Modify:对文件的内容进行修改;
Change:对文件的属性进行修改;
一般来说两次make后,第二次make结果是报错的,如果要不报错,继续编译的话,需在Makefile文件的依赖关系上加.PHONY:code
Makefile特殊符号
原:
code:code.c
gcc code.c -o code
clean:
rm -f code
加特殊符号:
code:code.c
gcc -o $@ $^
如果想执行make命令后不回显:
code:code.c
@gcc -o $@ $^
小程序进度条:1、回车换行;2、缓冲区
Makefile:
1 processbar:processBar.c main.c
2 gcc -o $@ $^
3 .PHONY:clean
4 clean:
5 rm -f processbar
-----------------------------------------------------------------------------------------
三个文件:main.c processBar.h processBar.c
mian.c:
1 #include "processBar.h"
2 #include <unistd.h>
3
4 int main()
5 {
6 processbar(100000);
7
8 // int cnt = 10;
9 // while(cnt>=0)
10 // {
11 // printf("%-2d\r",cnt);
12 // fflush(stdout);
13 // cnt--;
14 // sleep(1);
15 // }
16 // printf("\n");
17 return 0;
18 }
------------------------------------------------------------------------------------------------------------------------------------
processBar.h:
1 #pragma once
2 #include <stdio.h>
3
4 #define NUM 102
5 #define BODY '-'
6 #define RIGHT '>'
7 #define TOP 100
8
9 extern void processbar(int speed);
------------------------------------------------------------------------------------------------------------------------------------
processBar.c:
1 #include "processBar.h"
2 #include <string.h>
3 #include <unistd.h>
4 const char *label = "|/-\\";
5 void processbar(int speed)
6 {
7 char bar[NUM];
8 memset(bar,'\0',sizeof(bar));
9 int cnt= 0;
10 int len = strlen(label);
11
12 while(cnt<=TOP)
13 {
14 printf("[%-100s][%d%%][%c]\r",bar,cnt,label[cnt%len]);//没有\n,就没有立即刷新,因为显示器模式是行刷新
15 fflush(stdout);
16 bar[cnt] = BODY;
17
18 cnt++;
19 if(cnt<100) bar[cnt] = RIGHT;
20 usleep(speed);
21 }
22 printf("\n");
23 }
==============================================================================
git的基本使用:
git --version:查看版本是否安装,未安装->yum install git
git clone https://gitee.com/ZHAI_LL/linux1.git:gitee上文件下载到本地,后cd linux1
cp ../../processbar . -rf:将要上传仓库的文件复制到共享文件夹linux1中
git add . :将共享文件夹中与仓库中不同的文件添加到缓存区中
git commit -m "提交日志" :将文件提交并附上日志
git push :上传云端
git 的其他使用:
如果对于某个文件,如app.p,不想上传到仓库,那么可以在.gitignore文件中加入需要忽略的文件后缀*.p
git的配置(首次使用需要配置):
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
-----------------------------------------------------------------------------------------------------------------------------------------
gdb调试:
gcc默认编译的是release方式发布的,无法进行调试
如果需要调试,那么在Makefile文件中gcc命令后面加上-g:gcc -o $@ $^ -g
对于生成可执行程序,可通过,readelf -S mycode-debug | grep -i debug,查看调试信息
gdb mycode-debug:进入调试 q:退出调试 r:启动程序
l n:从第n行显示代码,接着通过回车显示剩余所有代码(list)
l 函数名:可以看具体的函数
b n:在第n行打断点(break point); info b:查看断点信息;
b mycode.c:19:对文件mycode.c的19行打断点
b main:对main函数打断点
d n:根据断点的编号n删除断点(delete)
n :逐过程调试(next); 调试结束后再r,可以重新运行调试
s :逐语句调试(step);
p 参数符号(print):监视参数状态,如p i;p top;p &i
disply i:对i的监视常显示;undisplay n:通过编号对常显示的参数取消监视
until n:在函数内跳转到指定的行调试
finish:跳出当前函数
c:运行到下一个断点(continue)
disable n:关闭 n号断点,但是没有删除n号断点
enable n:使能n号断点
set var i=98:调试过程中设置i的值为98
bt:查看各级函数的调用情况(breaktrace)
——————————————————————————————————————————————————————
进程:ps axj;查看linux下的正在运行的进程,ls /proc:查看动态运行的进程信息
当运行mycode程序时,ps axj | head -1 && ps axj | grep mycode:可查看对应mycode的进程状态
通过以上可查出进程的PID,如22146;
停止进程 kill -9 22146
在程序中可通过getpid()获取当前程序的进程PID
while : ; do ps axj | head -1 && ps axj | grep mycode | grep -v grep; echo "---------"; sleep 1; done
每隔1秒循环播放mycode进程的状态信息
一个操作系统,不会只运行一个进程,可以同时运行多个进程;
操作系统必须将进程管理起来,如何管理,先描述,后组织;
任何一个进程,在加载到内存形成真正的进程时,操作系统,要先创建描述进程(属性)
的结构体对象——PCB(process ctrl block)进程控制块,进程属性的集合
进程=内核PCB数据结构对象+代码和数据
操作系统通过对进程PCB单链表的增删查改实现对进程的组织
fork();//pid_t id = fork() 用于创建子进程,对于父进程返回子进程的PID,对于子进程返回0,若创建不成功返回-1;
父子进程共享代码(代码运行后不可修改),但不共享数据,因此对于父进程的id值和子进程不相同
这样对于不同的返回值,就可以区分进程,就可通过if等代码语句实现不同的代码功能
在数据这块,子进程并不是简单的将父进程的数据进行重新拷贝,因为如果父进程的数据很多,子进程所需的很少,
那么这种拷贝会造成资源的浪费,所以,操作系统采用了一种数据层面的写时拷贝手段,就是在子进程用到这个数据时,
再进行开辟内存空间,进行数据的拷贝并应用;
----------------------------------------------------------------------------------------------------------------------------------
为什么make完生成程序文件需要./才能运行,像一些指令pwd不需要,且可以直接运行?
因为有环境变量,系统会自动在PATH环境变量中目录下查找指令,查到了就会执行(echo &PATH)
[leil@leilei ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/leil/.local/bin:/home/leil/bin
以上为PATH环境变量路径;
如果想要能像系统命令那样直接执行程序,而不用./,该怎么操作?
1、将程序放到/usr/bin目录下可以直接实现
2、或者将当前程序文件添加到PATH环境变量路径里
PATH=$PATH:/home/lei/mycode
子进程可以继承父进程的环境变量
env:查找环境变量
添加环境变量:MY_VALUE=123456 ( export MY_VALUE=123456 )
取消环境变量:unset MY_VALUE
set:查看所有环境变量(包括本地变量)
本地变量是指只会在本BASH内部有效,不会被继承