Linux基础
|字数总计:2.6k|阅读时长:10分钟|阅读量:
参考
Linux 教程 | 爱编程的大丙
文件管理命令
相对路径和绝对路径
相对路径
./
:代表当前目前所在的目录,也可以使用.
表示
../
:代表当前目前所在的上一级目录,也可以使用..
表示
1
| pwd # Print Working Directory
|
绝对路径
- Linux: 起始结点为根目录,比如
/root/home
- Windows: 起始结点为某个盘符,比如
C:\\Users
命令提示行
1
| zwx@7049GP-TRT:~/learning$ whoami # 查看当前用户
|
其中的zwx
为当前用户名;7049GP-TRT
为主机名
1 2
| zwx@7049GP-TRT:~$ pwd /home/zwx
|
1 2 3
| zwx@7049GP-TRT:~/deeplearning$ cd zwx@7049GP-TRT:~$ pwd /home/zwx
|
-
$
对应普通用户,#
对应管理员用户
-
可执行程序对应的目录
1 2 3 4 5 6
| zwx@7049GP-TRT:~$ which pwd /usr/bin/pwd zwx@7049GP-TRT:~$ which whoami /usr/bin/whoami zwx@7049GP-TRT:~$ echo $PATH /opt/anaconda3/condabin:/home/zwx/.vscode-server/cli/servers/Stable-1e790d77f81672c49be070e04474901747115651/server/bin/remote-cli:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
|
命令行快捷键
Ctrl+A: 移动至行首
文件管理命令
1 2 3 4 5 6 7 8
| ls # list ls -a # list all ls -l # list ls -F # list ls -H # list ls -alFH # list ll = ls -l ll = ls -laF
|
文件类型
-
: 普通的文件, 在Linux终端中没有执行权限的为白色, 压缩包为红色, 可执行程序为绿色字体
d
: 目录(directory), 在Linux终端中为蓝色字体, 如果目录的所有权限都是开放的, 有绿色的背景色
l
: 软链接文件(link), 相当于windows中的快捷方式, 在Linux终端中为淡蓝色(青色)字体
c
: 字符设备(char), 在Linux终端中为黄色字体
b
: 块设备(block), 在Linux终端中为黄色字体
p
: 管道文件(pipe), 在Linux终端中为棕黄色字体
s
: 本地套接字文件(socket), 在Linux终端中为粉色字体
用户类型和权限
在Linux中有三大类用户: 文件所有者, 文件所属组用户, 其他人, 我们可以对同一个文件给这三种人设置不同的操作权限, 用于限制用户对文件的访问。
- 读权限:使用
r
表示, 即: read
- 写权限:使用
w
表示, 即: write
- 执行权限:使用
x
表示, 即: excute
- 没有任何权限:使用
-
表示
1 2 3
| - rwx rw- r-- | | | | 文件类型 文件所有者权限 文件所属组权限 其他人权限
|
目录的创建和删除
1 2 3
| mkdir dir1/dir2 -p rmdir dir1 # 删除空目录 rm dir1 -r # 递归删除目录
|
tree 命令
文件拷贝和目录拷贝
1
| cp sourcefile targetfile
|
1 2
| cp sourcedir targetdir -r # 递归拷贝 cp sourcedir/* targetdir -r # 拷贝sourcedir/目录下的所有文件到targetdir中
|
文件移动和重命名
1 2
| mv sourcefile targetdir/ # 移动文件 mv sourcedir/ targetdir/ # 移动目录
|
1 2
| mv sourcefile newfilename # 重命名文件 mv sourcedir/ newdirname # 重命名目录
|
查看文件类容
1
| cat filename # 显示文件的类容(仅限于小文件,否认不能全部显示)
|
1 2
| head -10 filename tail -10 filename
|
创建软链接和硬链接
1
| ln -s sourcefile targetdir/linkname
|
sourcefile建议使用绝对路径,这样创建的软链接可以移动位置
1
| ln sourcefile linkname # 创建硬链接
|
改变文件权限
1 2 3
| chmod who [+|-|=] mod filename who: u|g|o|a mod: r|w|x|- 4|2|1|0
|
修改文件所有者和所属组
1 2 3 4
| # 修改文件所有者 sudo chown 新的所有者 文件名 # 修改文件所属组 sudo chown 新的所有者:新的组名 文件名
|
tree命令
1 2
| ubuntu: sudo apt install tree centos: sudo apt install tree
|
1 2
| tree -L 2 # 只显示两层 tree -L 2 dirname/ # 指定目录
|
创建空文件
1
| touch filename # 如果文件已存在会更新文件的时间
|
重定向操作
1 2 3 4
| echo helloworld echo helloworld > temp # 覆盖 echo helloworld >> temp # 追加 cat temp
|
用户管理命令
切换用户
1 2
| su username # 不切换工作目录 su - username # 切换当前工作目录
|
创建和删除用户
1 2
| su - username # 验证用户是否创建成功 vim /etc/passwd # 是否能找到用户,用于验证用户是否创建成功
|
1
| sudo userdel username -r # 删除用户
|
添加和删除用户组
1 2
| sudo groupadd groupname # 添加组 sudo groupdel groupname # 删除组
|
1
| vim etc/group # 查看组的相关信息
|
修改用户密码
1 2
| passwd # 修改当前用户密码 sudo passwd username # 修改其它用户密码
|
压缩命令
Linux的常用压缩包格式
1
| tar.gz | .tgz | .tar.bz2 | .zip | .rar | .tar.xz
|
打包+压缩
查找命令
Vim的使用
GCC/G++
- 预处理: 在这个阶段主要做了三件事: 展开头文件 、宏替换 、去掉注释行
这个阶段需要GCC调用预处理器来完成, 最终得到的还是源文件, 文本格式
- 编译: 这个阶段需要GCC调用编译器对文件进行编译, 最终得到一个汇编文件
- 汇编: 这个阶段需要GCC调用汇编器对文件进行汇编, 最终得到一个二进制文件
- 链接: 这个阶段需要GCC调用链接器对程序需要调用的库进行链接, 最终得到一个可执行的二进制文件
1 2 3 4 5 6
| g++ -E ./helloworld.cpp -o ./helloworld.i # 预处理 g++ -S ./helloworld.i -o ./helloworld.s # 编译 g++ -c ./helloworld.s -o ./helloworld.o # 汇编 g++ ./helloworld.o -o ./helloworld # 链接 ./helloworld # 执行 hello, world!
|
1
| g++ ./helloworld.cpp -o ./helloworld # (预处理+编译+汇编)链接->可执行文件
|
使用gcc编译cpp文件需要加参数-l stdc++
,表示在链接时指定使用C++的动态链接库
1
| gcc ./helloworld.cpp -o ./helloworld -l stdc++
|
静态库和动态库
静态库
- 在Linux中静态库以lib作为前缀, 以.a作为后缀, 中间是库的名字自己指定即可, 即:
libxxx.a
- 在Windows中静态库一般以lib作为前缀, 以lib作为后缀, 中间是库的名字需要自己指定, 即:
libxxx.lib
静态库的制作
1 2 3 4 5 6 7
| # folder structure libcalculate ├── add.cpp ├── calculate.h ├── div.cpp ├── mul.cpp └── sub.cpp
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| double add(double, double); double sub(double, double); double mul(double, double); double div(double, double);
#include "calculate.h" double add(double x, double y){return x + y;}
#include "calculate.h" double sub(double x, double y){return x - y;}
#include "calculate.h" double mul(double x, double y){return x * y;}
#include "calculate.h" double div(double x, double y){return x / y;}
|
1 2 3 4
| # 编译不链接,生成.o中间文件,其中-I参数指明头文件的路径 g++ -c ./add.cpp ./sub.cpp ./mul.cpp ./div.cpp -I ./ # 进行打包,生成静态库文件libcalculate.a,其中rcs是ar命令的三个参数 ar rcs libcalculate.a *.o
|
静态库的使用
1 2 3 4 5
| # folder structure test ├── calculate.h # 静态库头文件 ├── libcalculate.a # 静态库文件 └── main.cpp
|
1 2
| # 进行编译,-L参数指明静态库文件的路径,-l参数指明静态库的名称(去掉前缀lib和后缀.a) g++ main.cpp -o test -L ./ -l calculate
|
动态库
- 在Linux中动态库以lib作为前缀, 以.so作为后缀, 中间是库的名字自己指定即可, 即:
libxxx.so
- 在Windows中动态库一般以lib作为前缀, 以dll作为后缀, 中间是库的名字需要自己指定, 即:
libxxx.dll
动态库的制作
-
将源文件进行汇编操作, 需要使用参数 -c
, 还需要添加额外参数 -fpic
或-fPIC
1
| g++ -c *.cpp -fpic -I ./path/to/head/
|
-
将得到的*.o
文件打包成动态库, 还是使用g++, 使用参数 -shared
指定生成动态库(位置没有要求)
1
| g++ -shared *.o -o libxxx.so
|
-
发布动态库和头文件
提供头文件和动态库文件: xxx.h
、libxxx.so
-
示例
1 2 3 4 5 6 7
| # folder structure libcalculate ├── add.cpp ├── calculate.h ├── div.cpp ├── mul.cpp └── sub.cpp
|
1 2
| g++ -c ./*.cpp -fpic -I ./ g++ -shared ./*.o -o libcalculate.so
|
动态库的使用
1 2 3 4 5
| # folder structure test ├── calculate.h # 动态库头文件 ├── libcalculate.so # 动态库文件 └── main.cpp
|
1 2 3 4 5 6
| # 进行编译和链接 g++ ./main.cpp -o test -L ./ -l calculate # 执行 ./test # 报错 ./test: error while loading shared libraries: libcalculate.so: cannot open shared object file: No such file or directory
|
动态链接器
动态链接器的搜索顺序:
- 可执行文件内部的
DT_RPATH
段
- 系统的环境变量
LD_LIBRARY_PATH
- 系统动态库的缓存文件
/etc/ld.so.cache
- 存储动态库/静态库的系统目录
/lib/
, /usr/lib
等
应用程序无法链接到动态链接库
1 2 3
| echo $LD_LIBRARY_PATH LD_LIBRARY_PATH=~/cudalearning/libcalculate:$LD_LIBRARY_PATH echo $LD_LIBRARY_PATH
|
修改用户目录下的~/.bashrc
文件(仅对当前用户生效)
1 2 3 4 5 6 7 8 9 10 11 12
| $ vim ~/.bashrc
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/cudalearning/libcalculate
$ tail -1 ~/.bashrc
$ source ~/.bashrc
$ ldd test libcalculate.so (0x00007f2d071e3000) ...
|
Makefile
1 2 3 4
| target1, target2, ... : depend1, depend2, ... command1 command2 ......
|
注意command前的缩进必须是真的Tab
,不可以是空格
1 2 3
| add, sub : add.cpp, sub.cpp g++ add.cpp -o add g++ sub.cpp -o sub
|
1 2 3 4 5 6
| test : main.cpp libcalculate.a g++ main.cpp -o test -L ./ -l calculate libcalculate.a : add.o, sub.o, mul.o div.o ar rcs libcalculate.a add.o sub.o mul.o div.o add.o, sub.o, mul.o, div.o : add.cpp sub.cpp mul.cpp div.cpp g++ -c ./add.cpp ./sub.cpp ./mul.cpp ./div.cpp -I ./
|
1 2 3 4 5 6 7 8 9 10
| target = test lib = libcalculate.a obj = add.o sub.o mul.o div.o
$(target) : main.cpp $(lib) g++ main.cpp -o $(target) -L ./ -l calculate $(lib) : $(obj) ar rcs $(lib) $(obj) %.o : %.cpp g++ -c $^
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| target = test lib = libcalculate.a
src = $(wildcard ./*.cpp)
obj = $(patsubst %.cpp, %.o, $(src))
$(target) : main.cpp $(lib) g++ main.cpp -o $(target) -L ./ -l calculate $(lib) : $(obj) ar rcs $(lib) $(obj) %.o : %.cpp g++ -c $^
|
1 2 3 4
| ... .PHONY:clean # 声明伪目标 clean: rm ./*.o ./*.a ./test
|
1 2
| make clean # 调用makefile中伪目标clean对应的命令 make # 重新调用make
|
1 2 3 4 5 6 7 8 9 10 11
| # folder structure ├── libcalculate │ ├── add.cpp │ ├── calculate.h │ ├── div.cpp │ ├── mul.cpp │ └── sub.cpp └── test ├── calculate.h ├── main.cpp └── makefile
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| target = test dir = ../libcalculate lib = libcalculate.a
src = $(wildcard $(dir)/*.cpp)
obj = $(patsubst %.cpp, %.o, $(src))
$(target) : main.cpp $(lib) g++ main.cpp -o $(target) -L $(dir) -l calculate $(lib) : $(obj) ar rcs $(dir)/$(lib) $(obj) %.o : %.cpp g++ -c $^ -o $(dir)/$@
clean: rm $(dir)/*.o $(dir)/*.a ./test
|
GDB调试