环境变量
echo $PATH
因此在执行shell命令时,会默认的在环境变量指定的目录下找有没有相应的可执行文件
printenv——查看全局的环境变量有哪些
set——查看当前local的环境变量
设置环境变量
直接设置,只在当前shell层可用,子shell中查不到设置的环境变量。如果想设置在子shell中也能查到的环境变量,就要用到export
unset——删除环境变量
scp
scp 用户名@ip地址:文件的绝对路径 要拷贝到本机的文件路径(相对,绝对都可以)
这种方式要输入密码,如何不输入密码拿东西呢?
需要做一些配置
第一步——产生公钥和私钥,将公钥交给另一台机器
ssh-keygen -t rsa
第二步——另一台机器获取到公钥之后,将公钥的内容追到之间的文件里
此时,分享公钥的机器可以不用输入密码的获取拿走了他公钥的机器的文件。但是反过来不行。
环境 centos 7,vim version 7.4
vim的使用
linux下的vim使用手册
$vimtutor
命令模式下
移动
- 行首——shift+0
- 行尾——shift+$
- 文件开头——gg
- 文件某一行——数字+G
- 文件的末尾——G
删除
- 删除光标位置的字母——x
- 删除光标前一个字母——X
- 从光标位置开始删除到第一个空格出现的位置——dw
- 删除从行首到光标的所有单词并把光标移动到行首——d0
- 删除光标位置开始之后是所有元素——D
- 删除光标所在行——dd
- 删除光标所在行开始的n行——ndd
复制粘贴
- 复制一行内容——yy
- 剪切一行内容——dd
- 复制n行内容——nyy
- 粘贴——p/P都可以,行不一样
- 替换一个字母——r+某字母
可视模式可以选中任意区间
- 进入可视模式——v
- 移动光标选中内容
- 按y复制内容
- 移动光标到目的地
- 按p或者P粘贴内容
查找
第一种查找方式
/+要查找的内容
对查找到的结果进行遍历
- 向下找——n
- 向上找——N
第二种查找方式
?+要查找的内容
对查找到的结果进行遍历
- 向上找——n
- 向下找——N
第三种查找方式
光标移动到要查找的单词上——shift+#
格式化文本
整体格式化——”gg“+"="+"G"
当前行向右移动一个tab——>>
当前行向左移动一个tab——<<
查看函数原型
光标先移动到函数名,然后执行——“2”+“shift”+“k” 或者“2“+”K”——2指的是查看第二章的内容
例如:
命令模式转编辑模式
- 光标之后——i
- 光标之前——a
- 行首——I
- 行尾——A
- 在上一行进入编辑模式——O
- 在下一行进入编辑模式——o
- 删除当前光标下的字母并进入编辑模式——s
- 删除当前行并进入编辑模式——S
末行模式
在末行模式下可以执行命令
- 执行命令——“:”+"!"+"要执行的命令"
字符串替换
- 修改当前行的第一个匹配到的要被替换字符串——":"+"s"+"被替换的字符串"+"新的字符串"
- 修改当前行的所有匹配到的要被替换字符串——":"+"s"+"被替换的字符串"+"新的字符串"+“g”
- 修改当全文的所有匹配到的要被替换字符串——":"+"%"+"s"+"被替换的字符串"+"新的字符串"+“g”
分屏
- 横着分——“sp”+文件名
- 竖着分——vsp+文件名
- 两个屏之间切换——ctrl+w+w
- 全部退出——qall
- 全部保存退出——wqall
使用vsp打开多个文件
: open 文件名 文件名
vim的配置
修改后配置文件之后,执行如下命令,即可使得配置生效
source ~/.vimrc
shell的快捷键
gcc
gcc工作流程
- 产生预处理文件——gcc -E hello.c > hello.i
- 生成汇编语言——gcc -S hello.i >hello.s
- 将汇编编译成二进制文件——gcc -c hello.s >hello.o
- 将二进制文件生成可执行文件——gcc hello.o
gcc相关参数
I(大写的AI)——指的是我要包含的目录是哪个
如果我要的头文件,当前目录下没有,我们可以用 -I 来指定一下头文件的路径
通过在代码中插入define片段,可以在不同的模式下执行不同的代码,
-D可以指定宏
例如上面的代码片段,这样前面#define DEBUG 0 才能执行红框选中的内容,但是每次都改源码很麻烦,还需要重新编译,我们可以利用gcc的 D参数来指定宏。使用下图中的方式的运行结果等同于在头文件中写了#define DEBUG 0
-L包含库路径
指定包含的库文件目录
-l (这是小L) 指定库
(就是那个.a文件)名
静态库的制作和使用——类似于当年的编译产出吧
.lib .dll 文件
- 静态库—— .a 结尾
- 共享库—— .so 结尾
制作过程
- 生成.o, gcc -c *.c -I./include
- 打包,ar rcs libxxxx.a *.o
- 使用的时候,参考 -L,-l参数
静态库
命名
libxxx.a——>对应于Windows里的.lib文件
制作步骤
- 编译为 .o 文件
- 将 .o 文件打包 (命令如下): ar rcs libxxxx.a file1.o file2.o .....
- 将头文件与库一起发布
例子:我要编译的文件的头文件在include目录中,我的文件在src目录中,如何用 -I 来指定头文件路径
执行命令如下
gcc -c add.c -I ../include/
制作静态库的例子
查看静态库文件信息
发布需要发布头文件和库文件
动态库
制作步骤
- 编译与位置无关的代码,生成 .o ——参数: -fPIC
- 将 .o 文件打包——参数: -shared
- 使用编译的时候与静态库一样,需要配置库的路径,保证ld链接器能够加载。方法有三
- 拷贝或链接到 /lib,/usr/lib这样的系统库目录
- 设置环境变量,LD_LIBRAY_PATH,export LD_LIBRAY_PATH=libpath:$LD_LIBRAY_PATH
- 修改 /etc/ld.so.conf ,ldconfig,这两步都需要root权限
详细解释何为与位置无关
0-3G为用户空间
3G-4G为内核区
受保护的头——例如#define NULL (VOID*)0
代码段——代码加载在这里
数据区分为data去和bss区
- data区——已初始化的全局变量
- bss区——未初始化的全局变量
接近3G的区域存储命令行参数+环境变量(e.g echo $SHELL)
堆区和栈区之间是共享库
对于静态库的生成文件(即 .a 文件),他放在代码段了,就成为了代码的一部分,因此编译的时候无需只带代码在哪,因为在加载的时候就已经加载到代码段了。
而共享库中的东西是我要用的时候才现去找,属于临时加载,用完就释放了。怎么找的?我知道库文件的名字,知道我需要的函数相对于库文件的偏移是多少,我找这个函数的时候,我知道他在哪个库,知道他的偏移,然后在共享库的位置上加上他的偏移来定位函数,这样才能去执行函数。
制作示例
第一步——生成与位置无关的 .o 文件
第二步——打包库的文件
第三步——发布(就是把第二步的 .so 文件移动)
第四步——我们用一下产出的 .so 文件
说明:动态库默认情况下是用不了的,需要设置一下。可以利用 ldd命令来检查生成的可执行文件的链接
可以看到,上面四个库有一个显示为 not found,因此在执行可执行文件的时候会报错(链接错误)。解决办法如下五种:
- 把库文件拷贝过来——不推荐
- 软连接——不推荐
- 硬链接——不推荐
- 环境变量——不推荐
补充:想让export命令永久生效,就把命令放在 .bashrc 文件中,否则再次登录的时候,命令就失效了。
- 推荐的方法——配置系统加载的链接库路径
vim /etc/ld.so.conf
然后在文件中添加路径
保存退出,然后执行命令,使得文件生效(-v是为了显示加载过程)
sudo ldconfig -v
静态库与动态库的对比
静态库
优点:1 执行快
2 发布应用时不需要发布库
缺点:1 执行程序体积会比较大
2 库变更时需要重新编译应用
动态库;
缺点:1 执行时需要加载动态库,相对而言,比静态库慢
2 发布应用时需要同时发布动态库
优点: 1 执行程序体积小
2 库变更时,一般不需要重新编译应用。但是如果接口修改了,则需要重新编译。