零星知识:
1.Windows下使用命令窗口使用ipconfig查看网络信息,Linux下用ifconfig。
1.前置知识1.配置虚拟机的网络
VMware---->选择虚拟机---->右键---->设置---->网络适配器---->桥接模式/NAT模式
NAT模式:在宿主机虚拟了一个路由器,虚拟机是该路由器子网的设备,外网不能访问内网,更安全;
桥接模式:路由器为虚拟机分配了IP地址,消耗了IP地址,但其他人可以访问虚拟机。(当电脑用不了虚拟机的时候,可让队友虚拟机开桥接模式,使用xshell共用一台虚拟机,但是要设置不同的用户名和密码)
设置网络,以固定虚拟机的IP地址:
1.桥接模式
更改网络模式为桥接模式
设置---->ipv4[ip–>自动,DNS–>自动,路由–>自动]
有线网络 :关闭—>开启
ping百度,看能否ping 通
根据自动时的详细信息将网络设置改为手动
ping百度,看能否ping 通
2.NAT模式
更改网络模式为桥接模式
然后其他同上
在Ubuntu上面安装ssh程序:sudo apt install ssh
装好之后检查是否安装成功(该进程是否运行):ps -elf|grep sshd
2.连接
在windows,iPad,手机等都可以来使用ssh协议连接。[在命令行中连接:ssh 用户名@IP地址]
或者用其他的ssh协议的软件,如xshell。
在xshell中,菜单栏 --工具 – 选项 – 鼠标和键盘,来设置鼠标的一些键的快捷操作。
菜单栏 – 文件 – 当前会话属性 – 键盘 --改变键序列。
3.unix,linux操作系统的体系结构:
应用程序
shell: 命令解析器
library routine: 公有函数库,封装系统调用
系统调用:内核提供给外部的接口
内核:CPU 进程 内存 硬件
4.POSIX为系统调用和系统库的接口提供了规范(IEEE 1003.1)
5.内核+支撑软件共同构成发行版本的操作系统,如Ubuntu,centOS,open SUSE
6.通过shell命令(命令解释器)来操纵操作系统。
2.用户系统模块
cat /etc/passwd 查看用户信息
从左往右依次是:登录名、口令、用户ID、组ID、注释字段、家目录和shell程序的位置
cat /etc/shadow 查看口令信息
who 当前谁在使用操作系统(谁登陆了)
cat /etc/issue 查看发行版信息
uname -a 查看内核版本
在www.kernel.org查看Linux所有的版本和源代码
两种用户:普通用户 特权用户
sudo临时提升为特权用户
sudo passwd 用户名,然后根据提示来修改密码
su 用户名 切换用户(switch user)
exit 退出登录
sudo useradd 用户名 -m [创建家目录] -s /bin/bash [指定shell的版本]
sudo userdel 用户名 -r (同时删除家目录,还在栈中的用户不能删除)
安全问题:
1.Ubuntu个人版禁止使用root直接登录
2.封禁策略
3.平常一般用普通用户
3.Linux文件系统
虚拟文件系统(vfs):树状结构 真实文件系统(磁盘存储)
绝对路径和相对路径
man命令所查的系统手册:
man命令中进入以后输入 “/关键字” 可进行查找
cd .(不变) cd … (上一级) cd(回到自己家目录) cd ~ (自己的家目录下) cd 路径
cd-(回到上一次,实际是回到env命令下oldpwd所指的路径)
pwd 当前工作目录
mkdir
rmdir 删除空目录
env 查看环境变量
ls -a[不忽略以.开始文件] -l[详细信息] -h[human readible更适合阅读]
ls -l 列出的文件信息:
第一列第一个字符中:d目录 l符号链接(软链接,相当于快捷方式) c字符设备 b块设备 -普通文件
接着是文件拥有者拥有组和其他人的读写执行的权限
接着是硬链接数(指向同一块磁盘空间),使用引用计数,目录中“.”指向本目录,“…”指向上一级目录。
拥有者,拥有组,大小,最后修改时间,文件名
tty 命令窗口
ln file1 file2 建立硬链接,不能给目录建立链接
每个目录结点的本质是一个链表,中包含了它所有孩子结点的指针
所以在某个目录中添加和删除文件要获得该目录的写权限。
cp file1 file2 目标文件存不存在会影响结果(覆盖或创建)
cp file1 dir1
cp dir1/ dir2/
-i[覆盖之前提示] -f[强制执行] -r[recursive,递归执行]
mv file1 file2 剪切/移动/重命名
-i -f依然有用,移动目录时可以不加-r,因为只改变了目录结点的硬链接
rm 删除
-r -i -f依然有用
root下禁止使用 rm / -rf
4.文件权限操作
chmod 修改文件权限,文字设定法和数字设定法
四种身份:u g o a,如chmod ugo-rx file1,chmod a=x,u=rw file2,chmod 664 file3
若要在某个目录下添加和删除文件,要有写权限
x权限影响cd, r权限影响ls,有r无x, 不能进入到目录项,ls -l只能看到名字和类型
文件创建掩码:如果掩码的的某一位为1,那么该位失效
umask xxx:临时修改掩码,只在本终端生效
5.查看相关命令
find 起始目录 查找条件
-name eg:find . -name “*file[a-z]?” find /user/include -name “stdio.h”
通配符:*(匹配任意字符串) ?(匹配任意一个字符) [] 如[0-9] (匹配集合中任何一个字符)
-user 按用户名查找
-group 按用户名查找
-uid 按用户ID查找
-gid 按组ID查找
-perm 按权限来查找 eg: find . -perm 775
-size [±]n[bcwkMG] 按文件大小来查找 eg:find . -size +1M
-type [bcdpfls]
-empty 查找空目录和空文件
按时间(a访问时间,c状态修改,m内容修改,min分钟,time天):amin cmin mmin atime ctime mtime
eg:find /etc amin -2 两分钟以内访问的 find /etc cmin +10 十分钟之前修改的
查找结果的与或非:-a -o !
eg:find / -mmin 720 -a -name “file” find . ! -type f
-exec 根据find的结果执行后续操作。
eg:find . -name “filea*” -exec ls -l {} ;
磁盘相关:
df -h 查看磁盘使用情况
du 目录 -h 查看某个目录下的磁盘使用情况
eg:du . -h -d 1 表示要查看的目录深度
cat命令:
-b 显示非空行的行数
-n 显示所有行的行数
-E 每一行行尾显示$
-s 把连续空行压缩为一行
file 文件名 查看文件类型
stat 文件名/目录名 :显示详细信息
which 文件名 :查找文件位置
locate 文件名 :查找文件,更快
locate命令查询的信息存储在数据库,查更快,而find文件是利用存储在文件中的索引来查找
重定向
重定向stdout:> 或 1>
重定向stderr: > 或 2>
重定向所有信息:&>
重定向输入:cat命令将一个文件链接到标准输出,当cat不加参数时,将标准输入连接到标准输出。
cat man sh查看更多重定向符号 >>追加模式重定向 eg: ls -al dir2 >>file1 创建一个空文件: touch 不存在文件,若为已存在文件,更新修改时间 echo -n >file2 cat >file3 按ctrl+d vi file4 使用route查看路由 查看文件:单页显示 more b/f/q/h less 同样 部分显示:head/tail -n 显示的行数,默认十行 sort 按字典序排序 uniq 去重显示(去掉的是连续重复的) CMD1|CMD2 把CMD1的stdout重定向到CMD2的输入 history 显示最近使用过的指令,eg:history|tail -n 5 字数统计:wc -l统计行 -w统计词 -c 统计字符 文件名,不加选项三个都显示 汉字编码:unicode 占三个字节 GB(K/2312) 两个字节对应一个汉字 编码转换:iconv -f gb2312 -t utf-8 file1 > file2( 选项是front to的意思) od -x 文件名:看二进制文件 Linux用的是utf-8编码(unicode的一个子集),Windows采用国标编码gb2312 重定向时不能重定向至本文件,因为重定向时会以“w”模式打开文件,会把源文件清空。 grep:先设计一个模板,把文件中所有符合模板的行打印出来。 格式:grep 正则表达式 文件名 -E 使用拓展的正则表达式规则 -n 还显示行号 正则表达式regular expression: 基本单位:普通字符 完全一致 . 匹配任意一个字符 [集合]匹配集合内的任意一个字符 基本单位? 基本单位出现0/1次 基本单位* 出现0-多次 基本单位+ 出现1-多次 (regex)把括号内的看做一个基本单位 regEx1 | regEx2 两个表达式符合一个就匹配 eg:grep -E “gr(e|a)y” file2 ^基本单位:匹配以基本单位开头的行 基本单位$: 匹配以基本单位结尾的行 < :表示单词的左边界 > : 表示单词的右边界 {n,m} n或者m或逗号跟其中一个可省略,表示基本单位出现逗号左边到逗号右边次 正则表达式应用 alias命令起别名,如alias ll = ls -al,在.bashrc中永久起别名 ctrl+a 鼠标回到当前行首 ctrl+e 鼠标回到当前行末 man -f 命令名 :显示哪些手册里有这个命令 man -k 命令名:所有与该命令有关的都打印出来 装man帮助文件:sudo apt install manpages-posix-dev 命令组合: CMD1;CMD2,先执行命令1,再执行命令2。 CMD1|CMD2 xargs : 把输入所谓参数来使用 eg:xargs ls -l xargs配合管道使用:CMD1|xargs CMD2 比如在一堆.c文件中找main函数:find . -name “*.c” |xargs grep -nE “int main” CMD1 `CMD2` CMD1 $(CMD2) 把命令2作为命令1的部分 eg:mkdir `date +%Y%m%d` ctrl+d:类似Windows下的EOF. ctrl+c:终止 打包:tar c(create) r(追加) x(释放) v(显示打包过程) f(指示打包文件的名字) z(使用gzip压缩) j(使用bzip2压缩) 压缩[压缩后不能追加]:bzip2,gzip 远程拷贝:scp(secure copy) scp [选项:-r 拷贝目录] 源 目的 本地写法:文件路径 远端写法:用户名@IP:文件路径 如: scp test.cc wz@220.56.45.5:~/dir1 ssh协议的免密码登录: 本端: 1. cd ~ 2.mkdir .ssh 3.ssh-keygen (生成公钥和私钥) 4.cd .ssh 5.scp id_rsa.pub 远端服务器 (拷贝公钥到远端服务器) 远端: 1. 登录到远端服务器 2. cat id_rsa.pub >> /home/wz/.ssh/authorized_keys gitee的免密码上传文件: 1.给自己的账号添加公钥 2.用ssh重新克隆仓库 光标移动: 普通模式-> i前 a后 I行首 A行尾 ->插入模式 命令模式下,h光标前,L光标后,k上,j下,^到行首,$到行尾,ctrl+b上一页,ctrl+f下一页,ctrl+u上半页,ctrl+d下半页,H当前页首,L当前页最后一行的行首, gg回到开始,G去末尾 n-往回走n行,n+往后走n行,nG 去第n行 == :n w 下一个单词,b 上一个单词 :set nu 显示行号 命令模式下编辑文件内容: x删除一个字符,dd删除一整行,ndd, dnd 删除n行,d^删除行首,d$删除行尾 dw删除一个单词,dnw删除n个单词,在vim里删除等价于剪切 p是粘贴,u撤回,ctrl+r撤回撤回 yy拷贝一整行,[n]yy拷贝n行 快速删除:d+t+“到要删除的位置后的第一个字符” 查找:/regex,匹配正则表达式,贪婪匹配,n下一个,N上一个 :set hlsearch 把所有找到的高亮显示 查找替换: : s/God/Dog 只换一个 : s/God/Dog/g 换这一行的所有匹配项 :7,9s/God/Dog/g 换第7行到第9行的所有匹配项 :%s/God/Dog/g 换查找的的所有都替换 visual模式: 按v进入横选,选中之后:d剪切,y拷贝,=代码对齐 gg = G全文代码对齐 竖选 ctrl+v 批量插入注释:ctrl+v ,移动光标,shift+i,输入内容,ESC 其他命令: ctrl+s:僵死状态,按ctrl+q解除僵死 :w保存,w!强制写入 :q退出,q!强退,:wq==:x, :X设置文件密码 多个窗口: :(v)new 文件名,新打开文件 :(v)split/sp 文件名,新打开文件 ctrl+ww,切换窗口 :qa全部关掉: :tabnew 文件名,多页签,切换:gt下一个,gT上一个 进入vim指定行数:eg: vim +500 file.txt 进入后到2000的第一个匹配项这里:vim +/2000 test.txt vim的配置:在~/.vimrc文件中,配置vim。 shell的配置:在~/.bashrc文件中,配置shell。修改后 source .bashrc让其马上生效。 在vimtutor练习。 在 /etc/sudoers 中给用户添加sudo权限 在不打开文件编辑器的同时批量修改多个文件内容 eg: sed “s/int/double/g” *.c find . -name “*.c”|xargs sed “s/int/double/g” -i选项,直接在本文件替换 awk 对比差异:vimdiff 文件名1 文件名2 … gcc -v查看gcc的版本号 gcc: 预处理:gcc -E test.c -o test.i #if xxx #endif #ifdef xxx #endif 动态多行注释 #ifndef xxx #endif 防御式声明 编译时-D DEBUG 等价于文件内#define DUBUG 编译:gcc -S test.i/c -o test.s 编译成汇编语言的一些结论: 1.变量名、数组名都丢弃,转换成为地址信息 2.类型信息转换成长度 3.循环的本质是goto 4.不同函数之间是相对独立的 常见汇编指令: q 64位 l 32位 push压栈 pop弹栈 mov拷贝 jmp跳转 jle <=jmp je ==jmp call调用 ret返回 sub减 add加 nop空 汇编:as test.s -o test.o nm test.o 查看符号文件 一步编译:gcc -c test.c -o test.o 链接: ld命令 gcc test.c/test.o -o test 其他: -D DEBUG类似于:#define DEBUG,其他也可以,相当于把宏传进去 gcc -c src/main.c -I head/ 指定头文件的搜索路径 优化:更改汇编代码的执行顺序,提高运行效率 -o0不优化 -o1 -o2 -o3然后优化依次提高 打开所有类型的警告:-Wall 《程序员的自我修养》 编译时加上-g选项(补充调试信息,还可以关掉一些导致指令执行顺序发生变化的优化) eg: 1. gcc test.c -o test -g 2. gdb test 指令: list、l显示代码,l [n],看第n行,l 函数名,看该函数,l 文件名,l路径名:文件名 r、run执行程序 break/b 行号n/函数名 打断点 c/continue,next/n 单步调试,跳过函数调用,相当于F10,step/s 相当于VS中的F11 info break 显示断点信息 delete 断点编号[不加删除所有] disable/enable 断点编号,使失效、生效 ignore 断点编号 次数 h获取帮助 查看执行状态[类似监视窗口]:print/p i print/p &i display 变量名:追踪打印 info display获取编号,undisplay 编号 :解除 查看内存:eg : x/3xw arr 表示显示3个单位16进制(x)显示每个单位4个字节(w)。 gdp调试段错误: core->保存程序出错时的堆栈现场 默认core文件不允许生成,如何使其可生成: ulimit -a :显示操作系统所有的限制 ulimit -c unlimited 要用gcc -g来编译,生成的文件core文件才能用来检查 gdb 文件名 core,然后用gdb来查看到底出现了啥错。 man core 步骤: 1.用gcc -g编译 2.解除core文件的大小的限制 3.执行程序,出现coredump 4 “gdb 可执行程序名 core” 进入gdb检查core文件 什么情况下会导致coredump: 访问了不该访问的内存地址,递归无出口而栈溢出等。 给gdb程序设置命令行参数: set args … show args来看参数 静态库:链接时拷贝一份库文件,打包到可执行程序中。 动态库:链接时不拷贝,只定位库文件位置,运行时再加载。 默认动态链接,静态链接时加编译选项:-static 创建静态库: 1.生成目标文件 (不能有main函数) 2.打包成静态库:eg: ar crsv libxxx.a xxx.o 3.将库文件转移到系统库目录:sudo cp libxxx.a /usr/lib 4.链接时-l库名,gcc main.o -o main -lxxx 如果删除库文件,不影响可执行程序,但不能重新链接 创建动态库: 1.在编译时,加-fpic或-FPIC,生成位置无关的目标文件 eg:gcc -c add.c -o add.o -fpic 2.打包成动态库: eg:gcc -shared -o libxxx.so xxx.o 3.拷贝sudo cp libxxx.so /usr/lib 4.链接时-l库名,gcc main.o -o main -lxxx 如果删除库文件,程序不能执行,恢复或者更新库文件,不需要重新链接,会执行新代码。 ldd命令:可以显示某个可执行文件的动态链接文件 eg:ldd main 动态库的更新: 1.把不同版本的的库文件存在/user/lib/中,用版本号区分 2. 若更新更改libxxx.so软链接的指向即可 eg: sudo rm libadd.so sudo ln -s libadd.so.0.0.1 libadd.so 工程管理工具 -> 增量编译 Makefile/makefile -> 规则的集合 语法: 目标文件:依赖文件集合 有些时候,使用make时并不希望得到最开始的目标文件,而是中间的目标文件。在make命令后添加目标文件的名字就能完成需求 : make [target] 伪目标:以永远不可能存在的文件作为目标 .PHONY: xxx xxx 集中整理伪目标,方便阅读 变量: 自定义变量:字符串[变量名]:=字符串[变量值] 使用"$(变量名)"来访问。 自动变量:随着规则变化,同一个变量名对应不同的值。 $(DIR)$(OBJS) 就是 ./main.o func.o 。第二项的前面是不会添加目录的字符串的。 通配符和模式匹配: %匹配字符:从上一个规则的依赖条件中,按照匹配格式匹配内容,每次匹配成功,就生成一个规则 %.o : %.c 在变量引用的时候,使用%匹配字符: srcs:=main.c add.c sub.c objs:=$(srcs:%.c=%.o) 内置函数: makefile的函数wildcard:从文件系统中提取文件名 eg: src:=$(wildcard src/*.c) subst/patsubst函数 for循环 实例: makefile里面还可以做其他事,@符号隐藏执行的命令 for循环 实例: makefile里面还可以做其他事,@符号隐藏执行的命令
6.单文件操作
7.打包和远程传输
//如
tar cvf packet.tar file*
tar cvfz packet.tar.gz file*
tar xvfz packet.tar.gz
tar cvfj packet.tar.bz2 file*
tar rvf packet.tar test.c
tar xvf packet.tar test.c
8.vim的操作
9.sed命令
10.编译相关
编译工具链 SDK
11.gdb
查看堆栈:backtrace/bt可执行程序大小 部署 更新 静态 大 容易 困难 动态 小 困难 容易
main:main.o add.o
gcc main.o add.o -o main
main.o:main.c
gcc -c main.c -o main.o
add.o:add.c
gcc -c add.c -o add.o
.PYONY:clean rebuild
clean:
rm -f main.o add.o main
rebulid:clean main
预定义变量:内部已经预定好含义的变量,可以手动修改含义。
使用目录作为变量也是可行的,但是要注意变量的引用是简单的字符串替换,比如DIR = ./,那么var:="how are you"
newvar:=$(subst you,me,$(var))
#objs:=$(srcs:%.c=%.o)
objs:=$(patsubst %.c,%.o,$(srcs))
list:=one two three
out:
for i in $(list);do echo $$i;done
out:=main
#srcs:=main.c add.c sub.c
srcs:=$(wildcard *.c)
#objs:=main.o add.o sub.o
#objs:=$(srcs:%.c=%.o)
objs:=$(patsubst %.c,%.o,$(srcs))
CC:=gcc
$(out):$(objs)
$(CC) $^ -o $@
%.o:%.c
$(CC) -c $^ -o $@
.PHONY:clean rebuild
clean:
$(RM) $(objs) $(out)
rebuild:clean $(out)
//利用循环生成三个独立的.c文件
CC:=gcc
LIST:=$(wildcard *.c) #1.c 2.c 3.c
EXE:=$(patsubst %.c,%,$(LIST)) #1 2 3
all:$(EXE)
for i in $(EXE);do $(CC) $$i.c -o $$i;done
.PHONY:rebuild clean
clean:
$(RM) $(EXE)
rebuild:clean all
//不用循环:
CC:=gcc
LIST:=$(wildcard *.c)
EXE:=$(patsubst %.c,%,$(LIST))
all:$(EXE)
%:%.c
$(CC) $^ -o $@
.PHONY:rebuild clean
clean:
$(RM) $(EXE)
rebuild:clean all
%.o,$(srcs))
list:=one two three
out:
for i in $(list);do echo $$i;done
out:=main
#srcs:=main.c add.c sub.c
srcs:=$(wildcard *.c)
#objs:=main.o add.o sub.o
#objs:=$(srcs:%.c=%.o)
objs:=$(patsubst %.c,%.o,$(srcs))
CC:=gcc
$(out):$(objs)
$(CC) $^ -o $@
%.o:%.c
$(CC) -c $^ -o $@
.PHONY:clean rebuild
clean:
$(RM) $(objs) $(out)
rebuild:clean $(out)
//利用循环生成三个独立的.c文件
CC:=gcc
LIST:=$(wildcard *.c) #1.c 2.c 3.c
EXE:=$(patsubst %.c,%,$(LIST)) #1 2 3
all:$(EXE)
for i in $(EXE);do $(CC) $$i.c -o $$i;done
.PHONY:rebuild clean
clean:
$(RM) $(EXE)
rebuild:clean all
//不用循环:
CC:=gcc
LIST:=$(wildcard *.c)
EXE:=$(patsubst %.c,%,$(LIST))
all:$(EXE)
%:%.c
$(CC) $^ -o $@
.PHONY:rebuild clean
clean:
$(RM) $(EXE)
rebuild:clean all



