Linux

发布于 2025-02-10  102 次阅读


一、Linux常用命令

小技巧:

(1)ctrl + shift + = 放大终端窗口
(2)ctrl + - 缩小终端窗口
(3)自动补全:在敲出 文件 / 目录 / 命令 的前几个字母之后,按下 tab 键,如果输入的没有歧义,系统会自动补全;如果还存在其他 文件 / 目录 / 命令 ,再按一下 tab 键,系统会提示可能存在的命令

(一)、shell

Shell:命令解释器,根据输入的命令执行相应命令

(二)、目录和文件

1. 类Unix系统目录结构

Ubuntu没有盘符这个概念,只有一个根目录/,所有文件都在它下面

2.用户目录

位于/home/user,称之为用户工作目录或家目录

3.相对路径和绝对路径

从/目录开始描述的路径为绝对路径,从当前位置开始描述的路径为相对路径

4.目录内容(ls)

a 列出隐藏文件,文件中以”.”开头的均为隐藏文件,如:~/.bashrc

l 列出文件的详细信息

R 连同子目录中的内容一起列出

5.切换目录(cd)

6.查看命令路径(which)

7.查看路径(pwd)

8.创建目录(mkdir)

9.删除空目录,删除文件/目录(rmdir rm)

10.创建/修改文件时间(touch)

touch文件不存在创建新的,文件存在更新文件时间

11.重命名/移动文件(rm)

看第二个是否为已经存在的文件夹

12.拷贝文件/目录(cp)

13.查看文件内容(cat)

14.树形显示目录(tree)

15.查看目录大小

16.查看磁盘使用情况

(三)、文件属性和用户用户组

1.查看到当前登录用户(whoami)

可用于写入脚本

2.更改文件目录访问权限(chmod)

权值计算:可读权限r :4 , 可写权限w :2 , 可操作权限x :1 , 没有权限- :0

例如:rw-rw-r-- 权值0664

数字设定法 chmod 修改权限权值 文件名

3.更改文件目录或用户的组(chown)

sudo用于临时增加当前用户权限到root

sudo chown 用户:用户组 文件名

(四)、查找与检索

1.文件名查找(find)

find 指定路径 name ' '

2.内容检索(grep)

常用参数:-n:显示行号,-i:不区分大小写,-R:连同子目录一起查找

grep 参数 ‘ ’ 路径

(五)卸载安装软件

1.apt-get

更新源:sudo apt-get update

安装包:sudo apt-get install package

删除包:sudo apt-get remove

2.deb包安装

3.源码安装

(六)磁盘管理

文件系统类型:

(1)挂载

(2)卸载

(七)压缩包管理

(八)网络管理

(1)ifconfig

(2)ping

(3)netstat

(4)nslookup

(5)finger

(九)常见服务器构建

1.ftp

2.nfs

3.ssh

(十)其他命令

1.看手册man

2.清屏clear

3.设置指令别名alias

4.显示当前时间date

4.权限掩码umask

5.创建终端

创建终端标签:Ctrl+Shift+t

切换标签  Alt+n (n=1)

新开终端 ctrl+shift+n

(十一)进程管理

1.查看当前在线用户who

所有的选项都是可选的,不使用任何选项时,who命令将显示以下三项内容:

    login name:登录用户名;

    terminal line:使用终端设备;

    login time:登录到系统时间;

2.监控后台进程ps

3.显示后台作业

ctrl z 挂起当前进程

第一列方括号中的数字表示作业序号,由当前运行的shell分配,而不是由操作系统统一分配的。在当前shell环境下,第一后台作业的作业号为1,第二作业的作业号为2…。第二列中的“+”号表示相应作业的优先级比“-”号对应作业的优先级高。第三列表明作业状态,是否为运行、中断、等待输入或停止等。最后列出的是创建当前这个作业所对应的命令行。

4.后台/挂起作业移到前台运行fg,挂起进程后台执行bg

5.进程发送信号

(1)查看信号编号

(2)既可以根据名字发送信号又可以根据编号发送

(3)大部分进程收到SIGTERM该信号就会终止,但是被挂起的进程不能处理信号,所以必须发SIGKILL信号,由系统强制终止进程。

6.查看当前进程环境遍历

(十二)、用户管理

1.创建用户

2.设置密码

3.切换用户

4.root用户 sudo su

5.删除用户

(十三)、关机重启

1.poweroff,shutdown 关机

2.reboot重启

(十四)、链接

链接有两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).建立硬链接时,链接文件和被链接文件必须位于同一个文件系统中,并且不能建立指向目录的硬链接。而对符号链接,则不存在这个问题。默认情况下,ln产生硬链接。如果给ln命令加上-s选项,则建立符号链接。

二、vi&gcc&gdb

(一)vim

1.Vi有三种基本工作模式:命令模式,文本输入模式,末行模式

(1)命令模式进入插入模式

i: 插入光标前一个字符

I: 插入行首

a: 插入光标后一个字符

A: 插入行未

o: 向下新开一行,插入行首

O: 向上新开一行,插入行首

(2)插入模式或末行模式进入命令模式

ESC

(3)末行模式下

w:存盘

wq:存盘退出

q!:不存盘强制退出

2.Vim基础操作

(1)移动光标

gg: 光标移动文件开头

G: 光标移动到文件末尾

(2)删除命令

x: 删除光标后一个字符,相当于 Del

X: 删除光标前一个字符,相当于 Backspace

dd: 删除光标所在行,n dd 删除指定的行数

D: 删除光标后本行所有内容,包含光标所在字符

d0: 删除光标前本行所有内容,不包含光标所在字符

dw: 删除光标开始位置的字,包含光标所在字符

(3)撤销命令

u: 一步一步撤销

U: 一次性撤销当前行所作的所有操作

Ctr-r: 反撤销

(4)重复命令

.  : 重复上一次操作的命令

(5)文本行移动:

>>: 文本行右移

<<: 文本行左移

(6)复制粘贴

yy: 复制当前行,n yy 复制 n 行

p: 在光标所在位置向下新开辟一行,粘贴

(7)查找命令

/: str查找

n: 下一个

N:上一个

(8)替换命令

把abc替换成123

:%s/abc/123/g

:%s/abc/123/gc(需用户确认)

(9)代码排版

gg=G: 代码自动缩进排版

3.Vim分屏操作

sp: 上下分屏,后可跟文件名

vsp: 左右分屏,后可跟文件名

Ctr+w+w: 在多个窗口切换

(二)、gcc

1.查看gcc版本号

-v / –v / –version 查看gcc版本号

2.-Wall 提示更多警告信息

3.-D 编译时定义宏,注意-D和之间没有空格

4.-g 包含调试信息 -On n=0∼3 编译优化,n越大优化得越多

(1)启动gdb

(2)GDB基本命令

  • run(或简写r):开始执行程序。
  • break(或简写b):设置一个断点。例如,break main会在主函数上设置一个断点。
  • delete 编号:删除断电
  • disable :禁用断点,但不断删除它。
  •  enable :启用之前禁用的断点。
  • next(或简写n):执行下一行代码,但不进入函数内部。
  • step(或简写s):执行下一行代码,如果是函数则进入函数内部。
  • print(或简写p):打印变量的值。例如,print i会打印变量i的值。
  • continue(或简写c):继续执行程序,直到下一个断点。
  • quit(或简写q):退出GDB。
  • list(或简写l):列出源代码。可以指定行号或函数名。
  • info:查看信息,比如info locals查看局部变量,info breakpoints查看所有断点。

三、makefile——项目管理工具

1.优点:

(1)可以使用便携的编译管理代码(不用每次都写复杂的编译命令)

(2)重用性极强,可以反复使用管理编译不同的工程

(3)节省编译时间

a.编译时间=(预处理+编译+汇编)(编译期,生成 .o文件)+链接(链接期,把所有.o文件和库文件链接生成可执行文件)

b.空间换时间:在第一次编译的时候不会节省编译时间,但会保存生成的中间 .o文件,在下一次编译的时候只需要重新编译修改的源文件,没有修改的源文件直接使用保存的 .o文件进行链接

c.如何识别哪个源文件被修改? 比较源文件的修改时间和.o文件的生成时间

2.注意

(1)mekefile文件必须以makefile或者Makefile命名

(2)使用#注释

(3)make命令执行makefile文件

(4)makefile脚本自顶向下建立依赖关系

(5)只会执行一个目标,如果需要多个目标,这些目标之间是主从关系

3.makefile三要素

(1)目标:完成编译生成可执行文件,目标一般为可执行文件的名字

(2)依赖:生成目标依赖文件和资源文件

(3)命令:根据依赖生成目标需要执行的命令

语法:

目标:依赖

(tba)命令

4.变量

(1)自定义变量

无需指定类型,默认都是字符串类型

变量名可以由大小写字母,数字,下划线构成,但不允许以数字开头

为了和高级语言区分开,一般使用全大写命名

使用变量$(变量名)

(2)特殊变量

$@:代表目标名

$^:代表当前所有依赖项

$<:代表依赖项中的第一项

5.函数和内建语法

(1)文件名处理函数

SRCFILE=$(wildcard *.c)

#使用该函数遍历当前文件夹下的所有文件,获取所有.c文件的名字,保存在SRCFILE中

(2)字符串处理函数

DSTFILE=$(patsubst %.c ,%.o,$(SRCFILE))

#使用该函数,把SRCFILE中保存的所有.c文件的名字替换成.o文件,替换完的结果保存在DSTFILE中

(3)内建语法

%.o : %.c

(tab)命令

6.常见变量

TARGET=myapp#存储目标文件名字

CC=gcc#存储编译命令

INCLUDE_PATH=../include#保存头文件路径

INSTALL_PATH=/user/bin#保存安装路径

LIBRARY_PATH=../library#保存库文件路径

CFLAGS=-I$(INCLUD_PATH) -c -g -Wall#编译选项

CPPFLAGS=-D#保存预处理选项

7.功能目标

与主目标不同,功能目标没有依赖 ,执行使用“make 功能目标名字“

(1)清除

clean:

(tab)rm -rf $(DSTFILE) $(TARGET)

(2)安装

install:

(tab)sudo cp $(TARGET) $(INSTALL_PATH)

(3)卸载

disclean:

(tab)sudo rm -rf $(INSTALL_PATH)/$(TARGET)

(4)打印

output:

(tab)echo $(INSTALL_PATH)/$(TARGET)

四、文件IO

1.文件描述符

一个进程默认打开3个文件描述符

STDIN_FILENO     0 标准输入

STDOUT_FILENO   1 标准输出

STDERR_FILENO   2 标准出错

新打开文件返回文件描述符表中未使用的最小文件描述符。

2.打开/关闭文件

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

(1)返回值:成功返回新分配的文件描述符,出错返回-1并设置errno

(2)flags参数

必选项:以下三个常数中必须指定一个,且仅允许指定一个。

* O_RDONLY 只读打开

* O_WRONLY 只写打开

* O_RDWR 可读可写打开

可选项

* O_APPEND 表示追加。如果文件已有内容,这次打开文件所写的数据附加到文件的末尾而不覆盖原来的内容。

* O_CREAT 若此文件不存在则创建它。使用此选项时需要提供第三个参数mode,表示该文件的访问权限。

* O_EXCL 如果同时指定了O_CREAT,并且文件已存在,则出错返回。

* O_TRUNC 如果文件已存在,并且以只写或可读可写方式打开,则将其长度截断(Trun-cate)为0字节。

#include <unistd.h>

int close(int fd); 

返回值:成功返回0,出错返回-1并设置errno

3.最大文件个数

查看当前系统允许打开最大文件个数

cat /proc/sys/fs/file-max

当前默认设置最大打开文件个数1024

ulimit -a

修改默认设置最大打开文件个数为4096

ulimit -n  4096

4.read/write

read函数从打开的设备或文件中读取数据。

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0

write函数向打开的设备或文件中写数据。

#include <unistd.h>                  

ssize_t write(int  fd, const  void  *buf, size_t  count);

返回值:成功返回写入的字节数,出错返回-1并设置errno

5.lseek

6.阻塞和非阻塞

读常规文件是不会阻塞的,不管读多少字节,read一定会在有限的时间内返回。

从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收到数据包,调用read从网络读就会阻塞,至于会阻塞多长时间也是不确定的,如果一直没有数据到达就一直阻塞在那里。

同样,写常规文件是不会阻塞的,而向终端设备或网络写则不一定。

(1)阻塞读终端

(2)非阻塞读终端

五、Linux文件系统

一个磁盘可以划分成多个分区,每个分区必须先用格式化工具格式化成某种格式的文件系统,然后才能存储文件,格式化的过程会在磁盘上写 一些管理存储布局的信息。文件系统中存储的最小单位是块(Block)

一个块究竟多大是在格式化时确定的,可以设置为1024 2048 4096 默认4096——4KB IO块stat查看

启动块是由PC标准规定的,用来存储磁盘分区信息和启动信息,任何文件系统都不能使用启动块。启动块之后才是ext2文件系统的开始,ext2文件系统将整个分区划成若干个同样大小的块组(Block Group),每个块组都由以下部分组成。

超级块(Super Block) 描述整个分区的文件系统信息,例如块大小、文件系统版本号、上次mount的时间等等。超级块在每个块组的开头都有一份拷贝。

块组描述符表(GDT,Group Descriptor Table) 由很多块组描述符组成,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符(Group Descriptor)存储一个块组的描述信息,和超级块类似,块组描述符表在每个块组的开头也都有一份拷贝,这些信息是非常重要的,一旦超级块意外损坏就会丢失整个分区的数据,一旦块组描述符意外损坏就会丢失整个块组的数据,因此它们都有多份拷贝。通常内核只用到第0个块组中的拷贝,当执行e2fsck检查文件系统一致性时,第0个块组中的超级块和块组描述符表就会拷贝到其它块组,这样当第0个块组的开头意外损坏时就可以用其它拷贝来恢复,从而减少损失。

块位图(Block Bitmap) 一个块组中的块是这样利用的:数据块存储所有文件的数据,比如某个分区的块大小是1024字节,某个文件是2049字节,那么就需要三个数据块来存,即使第三个块只存了一个字节也需要占用一个整块;超级块、块组描述符表、块位图、inode位图、inode表这几部分存储该块组的描述信息。块位图就是用来描述整个块组中哪些块已用哪些块空闲的,它本身占一个块,其中的每个bit代表本块组中的一个块,这个bit为 1表示该块已用,这个bit为0表示该块空闲可用。

为什么用df命令统计整个磁盘的已用空间非常快?

因为只需要查看每个块组的块位图即可,而不需要搜遍整个分区。相反,用du命令查看一个较大目录的已用空间就非常慢,因为不可避免地要搜遍整个目录的所有文件。

在格式化一个分区时究竟会划出多少个块组?

主要的限制在于块位图本身必须只占一个块。用mke2fs格式化时默认块大小是1024字节,可以用-b参数指定块大小,现在设块大小指定为b字节,那么一个块可以有8b个bit,这样大小的一个块位图就可以表示8b个块的占用情况,因此一个块组最多可以有8b个块,如果整个分区有s个块,那么就可以有s/(8b)个块组。格式化时可以用-g参数指定一个块组有多少个块,但是通常不需要手动指定,mke2fs工具会计算出最优的数值。

inode位图(inode Bitmap) 和块位图类似,本身占一个块,其中每个bit表示一个 inode是否空闲可用。

inode表(inode Table) ,一个文件除了数据需要存储之外,一些描述信息也需要存储,例如文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,也就是ls -l命令看到的那些信息,这些信息存在inode中而不是数据块中。每个文件都有一个inode,一个块组中的所有inode组成了inode表。

数据块(Data Block)根据不同的文件类型有以下几种情况 :对于常规文件,文件的数据存储在数据块中;对于目录,该目录下的所有文件名和目录名存储在数据块中,注意文件名保存在它所在目录的数据块中,除文件名之外,ls -l命令看到的其它信息都保存在该文件的inode中。注意这个概念:目录也是一种文件,是一种特殊类型的文件;对于符号链接,如果目标路径名较短则直接保存在inode中以便更快地查找,如果目标路径名较长则分配一个数据块来保存;设备文件、FIFO和socket等特殊文件没有数据块,设备文件的主设备号和次设备号保存在inode中。

1. 存储文件过程

(1)看BootBlock的磁盘分区

(2)看GDP块组描述表找到起始位置

(3)找空闲的inode节点,把文件属性存进去

(4)找到datablock先把文件内容存进去1

2. 读取文件过程

(1)通过BootBlock找到磁盘分区

(2)看GDP块组描述找到起始位置

(3)找inode table起始位置找到文件具体对应的inode节点,找到inode的节点标号,根据inode节点编号计算出inode的地址,根据inode的数据块指针周到 datablock中保存的文件内容

3. 删除文件过程

(1)BootBlock查看磁盘分区

(2)GDP块组描述符找到block bitmap和inode bitmap的起始位置

(3)inode bitmap 置0 blockbitmap 置0

4. 存储大文件

1.文件系统

(1)stat

stat既有命令也有同名函数,用来获取文件Inode里主要信息,stat 跟踪符号链 接,lstat不跟踪符号链接

(2)access

#include <unistd.h>

int access(const char *pathname, int mode);

按实际用户ID和实际组ID测试,跟踪符号链接

参数mode

R_OK 是否有读权限

W_OK 是否有写权限

X_OK 是否有执行权限

F_OK 测试一个文件是否存在

实际用户ID: 有效用户ID:sudo执行时,有效用户ID是root,实际用户ID是colin

(3)chmod

注意:函数

#include <sys/stat.h> 

int chmod(const char *path, mode_t mode); 

int fchmod(int fd, mode_t mode);

(4)chown

chown使用时必须拥有root权限。

#include <unistd.h>

int chown(const char *path, uid_t owner, gid_t group); 

int fchown(int fd, uid_t owner, gid_t group); 

int lchown(const char *path, uid_t owner, gid_t group);

(5)utime

<utime.h> 头文件

int utime(const char *filename, const struct utimbuf *times);
  • filename:指向文件名的指针,该文件的时间戳将被改变。
  • times:指向 utimbuf 结构体的指针,该结构体包含了新的访问时间和修改时间。如果这个参数是 NULL,则文件的访问时间和修改时间会被设置为当前时间。

utimbuf 结构体的定义如下:
struct utimbuf {
time_t actime; // 访问时间
time_t modtime; // 修改时间
};

(6)truncate

#include <unistd.h> 
#include <sys/types.h>
int truncate(const char *path, off_t length); 
int ftruncate(int fd, off_t length);

(7)rename

文件重命名

#include <stdio.h>
int rename(const char *oldpath, const char *newpath);

(8)chdir

#include <unistd.h>
int chdir(const char *path);
int fchdir(int fd);

改变当前进程的工作目录

(9)getcwd

获取当前进程的工作目录

#include <unistd.h>

char *getcwd(char *buf, size_t size);

(10)pathconf

#include <unistd.h>

long fpathconf(int fd, int name);

long pathconf(char *path, int name);

(11)link

a.创建一个硬链接

当rm删除文件时,只是删除了目录下的记录项和把inode硬链接计数减1,当硬链接计数减为0时,才会真正的删除文件。

#include <unistd.h>

int link(const char *oldpath, const char *newpath);

硬链接通常要求位于同一文件系统中,POSIX允许夸文件系统

符号链接没有文件系统限制

通常不允许创建目录的硬链接,某些unix系统下超级用户可以创建目录的硬链

创建目录项以及增加硬链接计数应当是一个原子操作

b.创建符号链接

int symlink(const char *oldpath, const char *newpath)

c.读符号链接所指向的文件名字,不读文件内容

ssize_t readlink(const char *path, char *buf, size_t bufsiz)

d.int unlink(const char *pathname)

如果是符号链接,删除符号链接

如果是硬链接,硬链接数减1,当减为0时,释放数据块和inode,如果文件硬链接数为0,但有进程已打开该文件,并持有文件描述符,则等该进程关闭该文件时,kernel才真正 去删除该文件

利用该特性创建临时文件,先open或creat创建一个文件,马上unlink此文件

2.目录操作

(1)mkdir

#include <sys/stat.h> 
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);

(2)rmdir

#include <unistd.h> 
int rmdir(const char *pathname);

(3)opendir/fdopenr

#include <sys/types.h> 
#include <dirent.h>
DIR *opendir(const char *name); 
DIR *fdopendir(int fd);

(4)readdir

#include <dirent.h>
struct dirent *readdir(DIR *dirp);
struct dirent { 
ino_t d_ino;                            /* inode number */ 
off_t d_off;                              /* offset to the next dirent */ 
unsigned short d_reclen;     /* length of this record */ 
unsigned char d_type;          /* type of file; not supported by all file system types */ 
char d_name[256];                /* filename */ 
};
//readdir每次返回一条记录项,DIR*指针指向下一条记录项

(5)rewinddir

#include <sys/types.h>
#include <dirent.h>
void rewinddir(DIR *dirp);
//把目录指针恢复到目录的起始位置。

(6)telldir/seekdir

#include <dirent.h> 
long telldir(DIR *dirp);
#include <dirent.h> 
void seekdir(DIR *dirp, long offset);

(7)closedir

#include <sys/types.h> 
#include <dirent.h>
int closedir(DIR *dirp);

写ls文件

哈尔滨理工大学 计算机科学与技术学院 计算机科学与技术专业 本科生
最后更新于 2025-02-27