Linux学习笔记二

上接笔记一

gcc serverc.c -o  server -Wall -g

文件检索

按文件属性查找

按文件名

 find +查找的目录+ -name+"文件的名字"    
 比如 find  /test/   -name "test1"

亦可以模糊查找,如果不知道名字的话 *代表多个  ?代表一个
find  /test/   -name "test?"

注意如果没有权限    用sudo 加上要执行的命令

             

文件大小

find /test/ -size  -10k
如果大于10k用加号  如果小于10k用减号  数要求是整数
k是小写的k  M是大写的M  !!


对于范围查找 每一个数都加上-size


find /test/ -size  -10k   -size +1k

                                  范围查找用的多!

文件类型

find /test/ -type p 
p是类型 还有什么别的啥的 在上面有

按文件内容查找

grep -r "查找的内容" 查找的路径 

这个是先输入查找内容 后输入查找路径

软件安装

在线安装

apt-get

  • 安装 sudo apt-get insatll tree 在线下载安装
  • 移除 sudo apt-get remove tree 
  • 更新 sudo apt-get update 然后加更新的列表 可以有多个
  • 删除缓存也就是删除所有软件安装包 sudo apt-get clean  实际上清除的是/var/cache/apt/archives目录下的.deb文件

aptitude

deb安装

安装 sudo dpkg -i xxx.deb

删除  sudo dpkg -r xxx  这里是用的别名 如果不知道名字用tab

源码安装

用源码可以看redeme文件 按操作进行安装或者去找网站,网站上会有安装方法

u盘挂载

压缩包管理

gzip   

.gz格式的压缩包  gzip *.txt 会将当前目录里面的txt文件全部压缩 会删除原有文件   解压gunzip *.gz

bzip

bzip与gzip类似,只是会保留原文件

tar

  参数  如果不是用z/j参数,该命令只能对文件或目录打包

  •  c 创建 压缩
  • x 释放 解压缩
  • v 显示提示信息 压缩解压缩 可以省略
  • f 指定压缩文件的名字

  •    z 使用gzip的方式压缩文件  .gz
  •    j  使用bizp2的方式压缩文件  .bz2

   压缩 : 

    tar zcvf  生成的压缩包的名字(xxx.tar.gz) 要压缩的文件或目录

     tar jcvf 生成的压缩包的名字(xxx.tar.bz2) 要压缩的文件或目录

注意下面那个是压缩的子文件的,压缩后的文件放到本目录里面

如果想要解压到指定了路径 加上参数-C

rar

 首先必须要手动安装该软件  sudo apt_get install rar

参数:

  •  压缩 :a
  • 解压缩 :x

比如多个压缩文件  rar a yasuoming *.txt

            压缩文件夹  rar a 形成的压缩名  被压缩的文件名

zip

压缩: zip 压缩包的名字   目录或者文件         如果想要递归操作(压缩文件里的文件)加-r

解压缩: unzip   压缩包的名字  目录或者文件

总结 :相同之处

 tar/rar/zip  参数 生成压缩文件的名字   压缩的文件或目录  ------------压缩时的语法

tar/rar/unzip 参数 压缩包的名字  解压缩目录------------------------------解压缩语法  rar没有参数

系统一些问题

who

输入who  因为打开了四个中断 所以pts后面显示那几个

ps 

ps a显示所有用户

ps au上面更加详细  PID是进程号 可以通过kill杀死

ps  aux显示没有终端的应用程序  输出的东西比较多,可以结合管道进行查找   

管道

指令一的输出为指令二的输入,如果使用了管道的话,指令一就不输出了,只有指令二的输出

   格式是  指令一 | 指令二         下面是一个例子 ps aux的查询结果作为内容查找的输入 去寻找bash

 注意上面最后一条的查询结果是grep进程在查找时占用的程序 并不是在pa aux的查询结果中

kill杀死进程

kill -l 查看信号

kill -9 进程号 是强制杀死进程

kill -15 进程号 是正常结束进程  

如果不加参数默认是-15结束

进程号可以通过ps aux并结合管道查出

env

查看当前进程的环境变量  内容也很多也需要管道  环境变量里面的值区分大小写

环境变量

linux下的环境变量是用的键值对 ,就像上面一样

path=第一个值: 第二个值

top

相当于任务管理器,会实时刷新 ,只能看

网络相关

主要介绍ip啥的

ifconfig

ping

 用Ctrl+c结束   看能上网吧 或者能联通别人吗

nslookup域名转换

address因为服务器可能不只是一台,所以有多个

用户管理

添加用户

sudo adduser 用户名  

这个是一个脚本,不支持用户名大写

su 用户名 切换用户

sudo  useradd -s  /bin/bash -g itcast -d /home/aa -m itcast

  •  -a 指定新用户登录时shell类型
  • -g 指定所属组,该组必须已经存在
  • -d 用户家目录
  • -m 用户家目录不存在时,自动创建该目录

这个用户名可以是大写

密码

添加密码

上述创建用户的时候没有输入密码 所以需添加密码  sudo passwd 用户名

修改密码

  • 直接passwd 修改本用户密码
  • sudo passwd 用户名 修改其他用户的密码

删除用户

sudo deluser 用户名

  不会删除家目录

sudo userdel -r 用户名 

会删除家目录

ftp服务器搭建  

使用vsftpd  

ftp服务器负责文件的上传和下载

服务器端

1.修改配置文件

   1.先安装

2. 去etc目录中打开这个文件  不知道啥名用tab补齐

3.修改配置

效果  大部分就是放开

  这里学习的时候出错了 因为没有打开anno_upload的那个

会出现异常

查看状态

因此关于3321 ExecStart=/usr/sbin/vsftpd /etc/vsftpd.conf (code=exited, status=2) 处理方法 就是修改配置

 但。。。。。还是有错,不知道为啥,以后来填

2.重启服务

sudo service vsfpd restart

客户端

客户端像服务器那样弄就可以了,如果自己连接自己就不用安装了

1.实名用户登录

ftp ip地址

 1.文件的上传 使用put 要注意当前目录 

如果登录的是a目录,那么上传只能上传a目录里的文件

2.文件的下载 get 文件名

注意:这里不能操作目录,对于目录的操作只能压缩打包!!

2.匿名用户登录

   ftp ip地址回车 输入annoyaous 密码直接回车

不允许匿名用户在任意目录直接切换  只能在一个指定的目录范围内工作 

可以在ftp服务器上创建一个匿名用户的目录 

如果不指定的话它的家目录在/srv/ftp/

3.lftp访问ftp服务器

lftp是一个ftp的客户端工具,可以上传和下载目录

安装 sudo apt-get install lfpt

连接 lftp ip地址

切换目录 lcd /目录

上传多个文件 mput  文件名 文件名2 文件名3

上传目录   mirror  目录名    比如mirror  muluming/

nfs服务器搭建

1.服务器端

1.创建共享目录

   1.安装:sudo apt-get install nfs-kernel-server

   2.

2.修改配置文件

 进入配置文件

加上下面这一行 /test是共享文件目录  *是所有网段  rw是读和写 sync是实时更新

3.重启服务

2.客户端

挂载服务器共享目录

ssh服务器

服务器端

  安装ssh

客户端

ssh 用户名@ip

让输入时是填yes 而不是y

scp命令

vim

公司里都是用的SI 即Sourceinsight  介绍代码阅读神器——Sourceinsight - 知乎

纯文本编辑器 也就没有鼠标

光标的移动

  • hjkl上下左右移动
  • 到头部 命令模式下按0
  • 到尾部 $符号
  • 到文件的首部 按两下g
  • 到文件的尾部  大写的G 或者shift+g
  • 到500行 

返回

  • 返回或者撤销 命令模式下按u  类似ctrl+u
  • 反撤销 ctrl+r   类似ctrl+y

删除

  • 删除当前单词 到单词的首部按dw
  • 删除本行光标前面的所有东西 d是删除 0是行首 因此d0是删除前面的
  • 删除本行光标后面的东西大写的d
  • 删除本行 两个d
  • 删除三行 3dd  四行4dd

复制粘贴

用5dd删除了五行 但是是到了粘贴板上  用p来进行粘贴

小p是粘贴到光标所在行的下一行 大P是粘贴到光标上一行   这里一般都是在光标之后,因此用p比较方便

复制  yy是复制一行  4yy是复制多行

选择

按v到可视模式 然后上下左右进行选择  按一下p是剪  按一下y是复制 

而这里的复制  比如p是在光标所在位置的后面(这里不是到光标的下一行) P是前面

需要注意的是这里面的删除就是剪切 

显示行号

:下面 set number

 查找

输入反斜杠 /内容   是向下查找

输入问号   ?内容   是向上查找

#  移动到某个单词上 按# 可以查看出现了多少次 

注意:这个遍历不能用方向盘的上下左右移动 ,需要用n或者大写n来移动   大写n向下 小写n向上缩进

缩进

当前行向右缩进 >>  向左缩进<<

函数提示文档

进入某个函数的文档,在当前单词下按shift+k  由于要跳 所以要shift

文本模式

什么光标前后啥的太复杂,直接用i就行,在光标的后面

当然o也需要记  是新开辟一行 在新的一行里准备输入

  • 在冒号下输入200 会跳到200
  • 替换

  • 某一行替换  光标到达某一行  :s/苍井空/苍空净  会替换某一行的第一个  如果想要替换那一行的所有  s/苍井空/苍空井/g
  • 整个文件替换  %s/苍井空/空京仓/g
  • 27到30行  :27,30s/内容1/内容2/g

冒号模式下可以输入命令  比如:!pwd   前面加上一个!

分屏模式

水平分屏  冒号模式下 sp  切换ctrl+ww 

如果想要关闭全部 :wall  :qall  如果想关闭某个 看光标在哪个里面 :q

垂直分屏 :vsp  文件名字  就可以切换到其他文件里面

使用前可以先用!ls看看有啥文件

vim打造IDE

便是修改配置文件

系统级配置文件目录 /etc/vim/vimc  修改后会对所有用户都生效

用户级配置文件目录 家目录/.vim/vimrc   vim是个隐藏目录

gcc

加上-o 后面加上重命名文件  如果不加名字 会生成a.out

静态库的制作

 1.命名规则

  1.   lib+库的名字 +.a
  2.   libmytest.a

2.制作步骤

  1.     生成对应的.o文件     用-c
  2.     将生成的.o文件打包   ar rcs+静态库的名字(libMytest.a)+生成所有的.o

3.发布和使用静态库

  1. 发布静态库
  2. 头文件

将hello.a移动到lib库中

优缺点

共享库

gbd的调试

  1. 首先生成带调试信息的可执行文件  gcc *.c -o app -g
  2. 然后打开这个可执行文件    gdb app
  3. 然后按l 可以查看文件  也就是 (gdb) l

     如果想要查看其他的内容 可以  (gdb) l 另一个文件名.c :20  返回第二十行

      如果想要查看其他文件的某个函数  可以  (gdb) l 另一个文件的名.c :insert  如果还想继续查看 按l 

      想要调回原来的 l  main .c :main

    4.设置断点 break 22 在22行打断点  break可以简写为b   

          条件断点  b 15 if i==6   直到15行i=6的时候才会停止

     具体的操作这里不加以赘述,什么跳出循环还是进入循环按c还是n就不说了 反正记住了也会忘

makefile

多个文件生成可执行文件

系统IO函数

unlink函数

处理软硬链接

c库中的rename

程序和进程

fork函数

创建一个子进程  pid_t fork(void);  返回两个值,第一个是子进程的id(非负整数) ,第二个返回0

父进程调用fork()返回子进程id,子进程调用fork返回0表示创建成功,在这里看返回值,如果返回值是大于0的则说明是父进程的,如果返回值是0则说明是子进程的

执行的结果

如果用for循环调用五次 不会出现5个子进程   由于新建了子进程,但是又回到了fork上面,所以子进程也会创建新的进程

 

fork完以后 两个的执行顺序看他们谁抢到cpu

父子进程资源共享

exec函数组

当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变,改变的是原先的数据全部没了。有下面几种

int execl(const char *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(const char *path, const char *arg, ..., char *const envp[]);

int execv(const char *path, char *const argv[]);

int execvp(const char *file, char *const argv[]);

int execve(const char *path, char *const argv[], char *const envp[]);

execlp函数

加载一个进程,借助PATH环境变量     

int execlp(const char *file, const char *arg, ...);              成功:无返回;失败:-1

    参数1:要加载的程序的名字。该函数需要配合PATH环境变量来使用,当PATH中所有目录搜索后没有参数1则出错返回。

    参数2以及后面的是传递命令行参数  最后面要加上NULL参数做标记结束

比如execp("ls","-a","-l",NULL)  给ls 传递参数-a -l  也就是  ls  -a -l

该函数通常用来调用系统程序。如:ls、date、cp、cat等命令。

execl函数

加载一个进程, 通过 路径+程序名 来加载。

execl("/bin/ls", "ls", "-l", "-F", NULL);    使用参数1给出的绝对路径搜索。

也可以用相对路径

其他函数

不是很常用  具体查看文档

回收子进程

孤儿进程

         孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程领养孤儿进程。

   init进程号是1,又称为孤儿院

僵尸进程

父进程创建子进程,父进程有义务将子进程杀死

 进程终止,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸(Zombie)进程。

为了回收使用下列

wait函数

父进程调用wait函数可以回收子进程终止信息。该函数有三个功能:

  • ① 阻塞等待子进程退出
  • ② 回收子进程残留资源
  • ③ 获取子进程结束状态(退出原因)。

    pid_t wait(int *status); 成功:清理掉的子进程ID;失败:-1 (没有子进程)

这里实际返回两个值,第一个值是正常返回的,第二个值是参数status,也就是传递一个指针进去,它会将状态修改到这个指针指代的地址中,配合下面进行查看退出是什么原因

 1.  WIFEXITED(status) 为非0    → 进程正常结束

         WEXITSTATUS(status) 如上宏为真,使用此宏 → 获取进程退出状态 (exit的参数)

     这两个是放在一起的

pid_t =wait(&status);
if(WIFEXITED(status)){
printf("exit with %d\n",WEXITSTATUS(status));
}

将状态修改到status,如果正常结束再使用下一个去获取状态

同理下一个是异常终止的情况

 2. WIFSIGNALED(status) 为非0 → 进程异常终止

         WTERMSIG(status) 如上宏为真,使用此宏 → 取得使进程终止的那个信号的编号。

一般终止的kill 编号是9和15 ,这个在上面kill部分中

socket

ip标识主机  端口号标识一个进程  

socket在网络环境中唯一标识一个进程 也就是ip+socket

socket是linux的一个伪文件 

socket全双工,既可以在一个时间写,又可以在同一时间读

socket成对出现

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

domain:
	AF_INET 这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址
	AF_INET6 与上面类似,不过是来用IPv6的地址
	AF_UNIX 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用
type:
	SOCK_STREAM 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
	SOCK_DGRAM 这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
	SOCK_SEQPACKET该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
	SOCK_RAW socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
	SOCK_RDM 这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序
protocol:
	传0 表示使用默认协议。
返回值:
	成功:返回指向新创建的socket的文件描述符,失败:返回-1,设置errno

网络字节序

网络数据流使用大端序

计算机上一般用的小端序

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

h表示host,n表示network,l表示32位长整数,s表示16位短整数。
如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。

ip地址转换

	#include <arpa/inet.h>
	int inet_pton(int af, const char *src, void *dst);
	const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

192.168.1.24------》网络字节序  inet_pton();

网络字节序-----------》点分十进制  inet_ntop();

三个参数 

  第一个参数 af 是选用的ipv4还是ipv6 对应AF_INET     和AF_INET6

  第二个参数是转换的字符串 

 第三个参数是生成的字符串  

ntop()另一个多的那个参数是大小

 数据结构

原先是sock sockaddr然后经过加工后改为了sockaddr_in但是人家不认,

比如定义了一个struct sockaddr_in addr;传递参数的时候要转换成sockaddr

(struct sockaddr *)&addr

在bind  accept connect传参的时候都需要将那个转换为原始的,但是定义的时候需要定义新的

也就是函数里面用到的是老的  定义的时候用新的_in

结构

struct sockaddr_in{
   sa_family_t        sin_family; 指明使用的ip协议  AF_INET
   in_port_t          sin_port;   指明端口号 但要注意传数据就要考虑字节序的问题
   struct in_addr     sin_addr;    ip地址结构,也有字节序
}                         如果想要加ip地址 需要.sin_addr.s_addr才能出来
 
 struct in_addr{
  uint32_t  s_addr;
}

套接字

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

domain:
	AF_INET 这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址
	AF_INET6 与上面类似,不过是来用IPv6的地址
	AF_UNIX 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用
type:
	SOCK_STREAM 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
	SOCK_DGRAM 这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
	


SOCK_SEQPACKET该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
	SOCK_RAW socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
	SOCK_RDM 这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序
protocol:
	传0 表示使用默认协议。
返回值:

bind函数

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd:
	socket文件描述符
addr:
	构造出IP地址加端口号
addrlen:
	sizeof(addr)长度
返回值:
	成功返回0,失败返回-1, 设置errno

listen函数

设置监听限定的

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
sockfd:
	socket文件描述符
backlog:
	排队建立3次握手队列和刚刚建立3次握手队列的链接数和

accept函数

阻塞,直到客户端连接

#include <sys/types.h> 		/* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockdf:
	socket文件描述符
addr:
	传出参数,返回链接客户端地址信息,含IP地址和端口号
addrlen:
	传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小
返回值:
	成功返回一个新的socket文件描述符,用于和客户端通信,失败返回-1,设置errno

返回新的 新的!!!!文件描述符

connect函数

客户端的

#include <sys/types.h> 					/* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockdf:
	socket文件描述符
addr:
	传入参数,指定服务器端地址信息,含IP地址和端口号
addrlen:
	传入参数,传入sizeof(addr)大小
返回值:
	成功返回0,失败返回-1,设置errno

其他

  • 在命名时经常吧xxxforxxx  命名为xxx4xxx

posted @ 2022-05-15 21:49  贪睡地蜗牛  阅读(72)  评论(0)    收藏  举报