文章目录
Linux命令基础
Shell
概述
shell:命令解释器,根据输入的命令执行响应命令
Shell是UNIX的命令解释器,Linux的命令解释器是bash,作用是一样的
cat /etc/shell
可以查看到当前Linux系统中有哪些shell
echo $SHELL
查看当前Linux系统正在使用的shell
Linux常见的shell:
- sh:已经被bash所取代
- bash:Linux默认的shell
- ksh:Korshell,兼容于bash
- tcsh:整合C Shell,提供更多的功能
- csh:已经被tcsh取代
- zsh:基于ksh发展出来的,功能更强大的shell
命令补齐:当路径下存在唯一选择时Tab键可以直接补齐,如果有多个匹配项按两次Tab键可以显示出所有匹配项
快捷键:
- Ctrl+p:上
- Ctrl+n:下
- Ctrl+b:左
- Ctrl+f:右
- Ctrl+d:①Del,删除光标后的字符;②表示EOF,相当于在终端中输入exit然后回车
- Ctrl+a:Home,跳转到行首
- Ctrl+e:End,跳转到行尾
- Ctrl+u:删除整行
- Ctrl+c:强制终止程序执行
- Ctrl+z:挂起一个进程。可以使用fg命令在前台恢复被挂起的进程,此时可以使用Ctrl+z再次挂起;使用bg命令在后台恢复被挂起的进程,此时不能使用Ctrl+z再次挂起
- Ctrl+s:中断控制台输出;
- Ctrl+q:恢复控制台输出
- Ctrl+l:清屏
目录和文件
类UNIX系统目录结构
**bin:**存放可执行文件
boot:内核和启动程序
dev:存放设备文件。因为在Linux中所见皆文件,所以各种硬件设备都以文件形式存放在该目录下
**etc:**系统软件的启动和配置文件信息
**home:**用户目录。包含系统中的所有用户。Linux系统默认有两个用户,一个是root,一个是使用者初始创建的用户
**lib:**库路径。操作系统使用的所有的库都存放在该目录中
media:磁盘目录。如果挂载的有磁盘就会以文件形式在media下显示
mnt:手动挂载的文件存放在mnt下
opt:可选的应用软件包(很少使用)
proc:系统内存的映射。可以直接访问这个目录来获取系统信息。这个目录的内容在内存上而不是硬盘上
root:表示root用户下的文件
当用户进入自己对应的文件夹(家)时,bash中的/
会变成~
。普通用户的家在/home/用户名/
,root用户的家在/root/
**usr:**UNIX software resource。用户安装的第三方文件、库都存放在该目录下
路径操作
相对路径:
- 用
.
表示当前目录,cd ./folder
表示进入当前文件夹下的一个叫folder的文件夹中 - 用
..
表示上一级目录 - 用
-
表示上一次进入的目录(不一定是上一级目录) - 用
~
表示当前用户的家的路径
绝对路径:以/
开头表示根目录
文件操作
**ls:**列出当前目录下的文件信息。选项-l
显示文件详细信息,可加参数变成ls -l dir
显示dir中的详细信息;-dl dir
表示显示文件夹dir本身的详细信息;-R
递归显示所有子目录中的文件;-h
以人类可读的形式显示信息
**文件类型:**普通文件-
、目录文件d
、字符设备文件c
、块设备文件b
、软连接l
、管道文件p
、套接字s
、未知文件
which:查看命令所在位置(绝对路径),如which date
pwd:显示当前所在的路径
隐藏$
之前的内容:
- 在家中利用ls命令找到.bashrc文件
- 然后使用
vi .bashrc
进入文件,在最后一行加上PS1=$
- 输入
:wq
保存退出,重新启动终端即可
mkdir:创建目录(文件夹)。选项-p
可以连同父目录一起创建
rmdir:删除空目录。选项-p
可以连同父目录一起删除
touch:在当前目录创建一个空文件
rm:删除文件。选项-r
递归删除所有子目录;-rf
强制递归删除
mv:移动文件。如mv file1 file2
**cp:**拷贝文件或者目录。选项-a
表示拷贝文件的全部信息(包括子目录),否则不能拷贝非空目录
cat:查看文件内容。也可以读取终端的内容。使用tac命令可以倒着读取文件内容
more:查看文本文件的内容。一次显示一屏,使用空格翻页,b前一页,回车下一行,q退出,v编辑
head:显示文件前10行。参数-数字
显示指定行
tail:显示文件最后10行,参数同head
**ln:**创建链接。创建软链接ln -s file file.soft
;创建硬链接in file file.hard
**软链接:**软链接相当于创建了一个快捷方式,内容就是指定的源文件的路径。如果创建软链接是使用的是相对路径,那么将软链接移动到其他目录后则不能使用,如果使用的是绝对路径,那么可以在任意地方使用
硬链接:对硬链接中的任意一个文件进行修改,其他文件也会一样变化,因为硬链接使得三个文件inode相同,映射硬盘中的同一份文件。删除其中一个硬链接不会删除硬盘中的文件,只会使硬链接计数减一,当硬链接计数为0时就会释放inode
wc:计算文件数据量。选项-c
或-bytes
或-chars
只显示字节数;-l
或-lines
只显示列数;-w
或-words
只显示字数
文件属性与用户用户组
whoami:查看当前登录用户
**chmod:**授予或撤销权限。格式为chmod [who] [+|-|=] [mode] 文件名
。其中参数who中,u表示文件所有者、g表示同组用户、o表示其他人、a表示所有用户;参数+表示添加权限、-表示撤销权限、=表示赋予权限并取消其他权限;参数mode中,r或4表示读权限、w或2表示写权限、x或1表示执行权限。或者格式chmod 三位数字 文件名
。其中参数三位数字中,分别表示ugo用户的权限,每一位的值为该用户权限对应数字之和
创建用户或用户组:创建用户sudo adduser 新用户名
;创建用户组sudo addgroup 新组名
删除用户或用户组:删除用户sudo deluser 用户名
;删除用户组sudo delgroup 组名
chown:修改文件所有者或者用户组。修改所有者sudo chown 新用户名 待修改文件
;修改用户组sudo chgrp 新用户组名 待修改文件
;一次性修改用户和用户组sudo chown 新用户名:新用户组 待修改文件
umask:指定创建文件时的掩码。掩码的计算为777减去文件想要赋予的权限,再减去执行功能x的值
查找与检索
find:查找文件或者目录。选项-name
按名字查找;-type
按类型查找;-mandepth 深度
搜索深度,需要紧跟在find命令后添加;-size +最小值 -size -最大值
按大小搜索,单位为b(block=512bytes)、c(byte)、w(two-byte words)、k(KB)、M(MB)、G(GB),区分大小写;-atime/mtime/ctime 距今多长时间(天)
按最近访问/属性更改/内容改动时间查找;-exec
将find搜索的结构集执行某一指定命令,其中{}
表示将-exec之前的命令结果当做参数传输、必须以\;
结尾表示是两条命令;-ok
以询问交互的方式执行某一命令
使用-exec的命令find ./ -name '*tmp*' -exec ls -l {} \;
和使用xargs的命令find ./ -name '*tmp*' | xargs ls -l
作用是相同的。区别在于-exec会将find执行的结果集一次性交给下一条命令执行,而xargs会在结果集过大时分批交给下一条命令执行,效率更高。但是当文件名出现空格时,xargs因为是按照空格对文件进行划分,所以会出现错误,这时需要加上-print0表示以NULL来划分文件来解决find ./ '*tmp*' -print0 | xargs -print0 ls -l
grep:根据文件内容查找。选项-r
递归进入子目录搜索;-n
给出查找到的内容所在的行号
grep一般和ps命令结合使用。ps aux | grep 字符串
,表示寻找和某个字符串相关的进程结果集。搜索结果至少有一条,是grep自身
安装和卸载软件
apt-get:软件包管理工具,适用于Ubuntu、Debian。对于CentOS使用的是yum
从软件仓库进行软件安装和卸载:
- 联网
- 先选择下载源
- 再从软件仓库更新安装源:
sudo apt-get update
- 安装软件:
sudo apt-get install 软件名
- 卸载软件:
sudo apt-get remove 软件名
Linux有两大分支,一个是Red Hat,代表是Red Hat、CentOS。一个是Debian,代表是Debain、Ubuntu
在Debian分支下的所有软件安装包都是以.deb结尾
安装软件包命令:sudo dpkg -i xxx.deb
删除软件包命令:sudo dpkg -r xxx.deb
利用源码安装软件:
- 解压源代码包
- cd进入到安装目录中
- 使用
./configure
命令检测文件是否缺失,创建Makefile,检测编译环境 - 使用
make
编译源码,生成库和可执行程序 sudo make install
把库和可执行程序安装到系统路径下sudo make distclean
删除和卸载软件
压缩包管理
**tar:**压缩并打包和解压缩。选项-zcvf 要生成的压缩包名 需要压缩的文件列表
生成一个压缩包,其中z表示使用gzip压缩,c表示创建,v表示把需要打包压缩的文件打印在终端上,f表示创建的是一个文件;-zxvf
解压文件
tar -zcvf
和tar-zxvf
中真正实现的压缩和解压缩的是gzip和gunzip命令,但是gzip只能压一个文件,不能多,也不能是目录。tar -jcvf
和tar -jxvf
表示使用bzip2来压缩和解压缩
rar:把文件压缩成.rar类型的压缩包rar a -r yyy.rar xxx
。解压缩使用unrar命令unrar -x yyy.rar
zip:把文件压缩成.zip类型的压缩包zip -r yyy.zip xxx
。解压缩使用unzip命令unzip yyy.zip
进程管理
who:查看当前在线上的用户情况。显示登录用户名、使用终端设备、登录到系统的时间
ps:用于监控后台进程的工作情况。ps aux
选项a表示all查看系统所有用户的进程、u表示查看进程所有者及其他详细信息、x表示显示没有终端控制的进程
jobs:显示当前shell下正在后台运行哪些作业
fg/bg:前后台切换。bg将挂起的进程提到后台执行,fg将后台进程或挂起进程放到前台执行
kill:杀死进程
env:显示所有环境变量
top:任务管理器
Vim
vim命令
vi:是一个文本编辑程序,没有菜单,只有命令
vi三种工作模式:命令模式、文本输入模式、末行模式
三种工作模式的切换:
vi hello.c
首先进入的是命令模式- 在命令模式中通过按i/a/o/s/I/A/O/S进入到文本模式
- 在文本模式中按ESC返回命令模式
- 命令模式输入
:
进入末行模式 - 在末行模式连按两次ESC或者执行一个末行命令返回命令模式
- 在命令模式输入ZZ退出
文本模式不能直接切换到末行模式,只能先返回到命令模式再切换到末行模式
命令模式切换文本模式:输入i表示在光标之前插入,a表示在光标之后插入,o表示在光标所在行的下一行插入,I表示在光标所在行的行首插入,A表示在光标所在行的行尾插入,O表示在光标所在行的上一行插入,s表示删除当前光标下的字符然后插入,S表示删除光标所在行然后插入
跳转到指定行:在命令模式下直接输入“行号+G”,缺点是只能盲打,不会显示;在末行模式下输入行号然后回车
跳转文件首:在命令模式下输入gg
跳转文件尾:在命令模式下输入G
自动格式化程序:在命令模式下输入gg=G
括号对应:在命令模式下输入%
删除单词字符:在命令模式下输入x
删除整个单词:在命令模式下,当光标在单词首字符处时输入dw
光标移至行首:在命令模式下输入0
光标移至行尾:在命令模式下输入$
删除从光标至行尾的所有字符:在命令模式下输入D
或者d$
删除从光标至行首的所有字符:在命令模式下输入d0
删除若干行:在命令模式下输入dd
删除光标所在行,输入行数dd
删除包括光标所在行以下若干行
替换光标下字符:在命令模式下输入r预替换字符
删除指定范围的字符:在命令模式下输入v
使用可视功能,然后利用hjkl移动光标选中字符,最后按d
删除
**复制行:**在命令模式下输入yy
复制光标所在行,输入行数yy
复制包括光标所在行以下若干行
**粘贴:**当剪切的内容是一整行时,在命令模式下输入p
将内容粘贴到光标所在行的下一行;输入P
将内容粘贴到光标所在行的上一行。当剪切的内容是单词时不会自动换行
vi中没有真正的删除,删除的内容其实都在缓冲区,可以直接粘贴,删除相当于剪切
**撤回:**在命令模式下输入u
**反撤销:**在吗命令模式下输入Ctrl+r
匹配字符:在命令模式下输入/
进入末行模式,然后输入想要匹配的字符后回车返回命令模式,在命令模式下按n
查找下一处匹配;在命令模式中输入*
对光标下的字符进行查找,再按*
查找下一处匹配,按#
查找上一处匹配
替换字符:在末行模式下输入:s /待搜索的字符串/待替换的字符串
在光标所在行上进行替换;输入:%s /待搜索的字符串/待替换的字符串/g
在全文内进行全部替换,如果不加/g
每行最多替换一个;输入起始行,末尾行s /待搜索的字符串/待替换的字符串/g
在指定行范围内进行全部替换
Ctrl+p和Ctrl+n在末行模式下也可以调用上一条或者下一条命令
分屏:在末行模式下输入:sp
进行上下分屏;输入:vsp
进行左右分屏,Ctrl+w+w进行分屏间的切换,q退出光标所在分屏,qall退出所有分屏
查询光标所在函数的手册:在命令模式下输入K
显示手册中第一个对应的部分,输入卷数K
跳转到对应卷的部分
查询光标下宏定义:在命令模式下输入[d
查询定义语句
**执行shell命令:**在末行模式下输入:! Shell命令
,执行命令后按回车回到vim中
个性化vim
修改配置文件:
/etc/vim/vimrc
修改vim的配置文件~/.vimrc
用户下的隐藏配置文件,优先级更高
GCC
gcc编译步骤:预处理、编译、汇编、链接
**预处理:**使用gcc -E
,hello.c预处理形成hello.i。展开宏、头文件;替换条件编译;删除注释、空行、空白
**编译:**使用gcc -S
,hello.i编译成hello.s。检查语法规范。消耗时间、系统资源最多
**汇编:**使用gcc -c
,hello.s汇编成hello.o。将汇编指令翻译成机器指令
链接:使用gcc
,hello.o链接到a.out。数据段合并,地址回填。-o
不是链接阶段的参数,是用于指定形成文件的名字的
后一阶段的命令都包括了前一阶段的操作,即gcc -S
包括了预处理和编译的过程;gcc -c
包括了预处理、编译和汇编的过程;gcc
包括了预处理、编译、汇编、链接的过程
参数:
-I 路径
:指令头文件所在目录的位置-g
:编译时添加调试语句,用于支持gdb调试-On
:编译优化,n取1、2、3,n越大优化得越多-Wall
:显示所有警告信息-D
:向程序中动态注册宏定义
静态库和共享库
静态库:在编译时将静态库的代码加入到源码中一起编译,成为程序的一部分
共享库(动态库):在程序执行到需要调用共享库时再调用库中的代码,多个源文件共享一个共享库
静态库占用空间多,但是速度较快;共享库占用空间少,速度较慢
静态库
创建静态库:ar rcs libxxx.a file.o
。静态库后缀为.a,名称必须是lib。只能用.o文件来创建静态库
使用静态库:在编译时将静态库一起编译gcc yyy.c libxxx.a -o a.out
头文件守卫:防止头文件重复包含
#ifndef _MYMATH_
#define _MYMATH_
//头文件的内容
int add(int a, int b);
#endif
动态库
动态库在链接时不会进行固定地址绑定,而是采取延迟绑定,在程序运行到需要执行动态库中的代码时再用动态链接器去链接地址
创建动态库:创建.o文件时加上参数-fPIC
生成与位置无关的代码(@plt)。然后使用gcc -shared -o libxxx.so file.o
命令制作动态库
使用动态库:编译可执行程序时指定动态库gcc test.c -o a.out -l xxx -L 库路径
。-l
后加库名,-L
后加库路径
链接器:工作于链接阶段,工作时需要-l
和-L
动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置。通过修改环境变量指定动态链接器寻找动态库的位置①export LD_LIBRARY_PATH=动态库路径
临时指定环境变量,关闭终端后失效;②打开~/.bashrc
配置文件,添加export LD_LIBRARY_PATH=动态库路径
保存并退出,然后在终端中输入. .bashrc
执行配置文件,或者使用source .bashrc
命令使配置文件生效,或重启终端即可使环境变量永久生效。动态库文件最好写绝对路径;③将创建的动态库放到标准C库/lib
中;④修改配置文件sudo vi /etc/ld.so.conf
,将动态库路径添加在ld.so.conf文件中,然后使用sudo ldconfig -v
使配置文件生效
ldd:查看可执行文件需要的所有动态链接库
Linux内存布局
0-3G:.text代码段;.rodata只读数据区;.data数据段,存放初始化为非零的数据;.bss静态内存分配段,存放为初始化的数据;heap堆区,从低地址向高地址成长;.so加载位置,存放动态链接库;stack栈区,从高地址向低地址成长;环境变量、main参数,存放环境变量和参数;
3-4G:存放kernel内核
链接阶段进行数据段合并,将都是只读的.text代码区和.rodata只读数据区合并,将都是可读可写的.bss静态内存分配段和.data数据段合并
GDB
gdb检查的是逻辑错误,不是语法错误,语法错误是靠gcc来检查的
想要可执行文件是可被调试的,在链接时需要加上-g
选项
调试文件:gdb a.out
对文件开始进行调试
列出文件源码:list n
从第n行开始输出,每次显示10行,再次输入list或l就显示后面十行
设置断点:break n
或b n
在第n行设置一个断点;b n if 条件语句
实现条件断点,当满足条件时才阻断;删除断点d breakpoints n
删除第n行的断点
运行:run
或r
开始执行程序,在断点处暂停
按过程前进:n
,如果是函数,会直接执行完函数体到下一行
按语句前进:s
,如果是函数会进入到函数体内部。如果是系统函数则不能进入,必须跳过
查询变量的值:p 变量名
显示变量当前的值
查询变量的类型:ptype 变量名
显示变量的类型
运行到下一个断点:continue
会直接运行到下一个断点,如果后续没有断点则直接运行至程序结束
退出调试:quit
单步执行:start
默认从程序第一行开始执行,停留在第一行。使用n
和s
可以往下执行
结束当前函数:finish
结束函数后返回到函数调用点
设置main命令行参数:①set args 参数列表
;②run 参数列表
查看信息:info b
查看断点信息表
栈帧:随着函数调用而在stack上开辟的一片内存空间。用于存放函数调用时产生的局部列表和临时值
查看函数的调用的栈帧和层级关系:backtrace
或bt
切换栈帧:frame n
切换到序号n的函数栈帧
跟踪变量的值:display 变量名
持续跟踪观察变量值的变化。取消跟踪使用undisplay 编号
命令
Makefile
概述:文件名为makefile或者Makefile。用于项目管理
规则:
#目 标:依赖条件
# 命令
hello:hello.c
gcc hello.c -o hello
使用:在Makefile的目录下中输入make
命令即可。选项-n
模拟,可以模拟执行后的结果,防止误操作,主要用于make clean命令。-f
指定文件执行make命令make -f xxx.mk
,当Makefile的名称不是“makefile”或“Makefile”时使用这个命令执行make命令
注释:#
放在行首表示单行注释
基本原则:
-
若想生成目标,检查规则中的依赖条件是否存在,如不存在,则寻找是否有规则用来生成该依赖文件
hello:hello.o gcc hello.o -o hello hello.o:hello.c gcc -c hello.c -o hello.o
-
检查规则中的目标是否需要更新,必须先检查它的所有依赖,依赖中有任一个被更新,则目标必须更新
a.out:hello.o add.o gcc hello.o add.o -o a.out hello.o:hello.c gcc -c hello.c -o hello.o add.o:add.o gcc -c add.c -o add.o
所以将编译和链接分开进行,这样Makefile只会重新编译改动过的文件,节省资源
Makefile将文件的第一行作为最终命令,所以生成依赖文件的命令应当放在后面。也可以使用默认命令ALL:最终生成的文件
指定Makefile应该生成的文件,这样会执行Makefile中的命令直到生成指定的最终文件
函数:
src = $(wildcard ./*.c)
:找到当前目录下后缀为.c的文件,赋值给src。参数wildcard表示函数名;*.c表示函数参数;src用来保存返回值obj = $(patsubst %.c,%.o, $(src))
:把src变量中的所有的.c文件替换为.o文件
make clean命令:删除文件,需要自己编写。目标为clean,没有依赖,使用rm命令删除文件时,在rm前加上-
可以在删除不存在文件时不报错继续执行。
自动变量:
$@
:表示规则中的目标$<
:表示规则中的第一个条件。在模式规则中,可将依赖列表中的依赖依次取出套用模式规则$^
:表示规则中的所有条件,组成一个列表,以空格隔开,不包含重复项
自动变量只能出现在规则的命令中
模式规则:
%.o:%.c
gcc -c $< -o $@
静态模式规则:指定对哪一个依赖运用模式规则。在有多个模式规则时使用,避免歧义
$(obj):%.o:%.c
gcc -c $< -o $@
伪目标:不管条件满足与否目标都必须执行。主要用于clean、ALL目标,避免在存在同名文件时无法执行目标
.PHONY: clean ALL