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.命名规则
- lib+库的名字 +.a
- libmytest.a
2.制作步骤
- 生成对应的.o文件 用-c
- 将生成的.o文件打包 ar rcs+静态库的名字(libMytest.a)+生成所有的.o
3.发布和使用静态库
- 发布静态库
- 头文件
将hello.a移动到lib库中
优缺点
共享库
gbd的调试
- 首先生成带调试信息的可执行文件 gcc *.c -o app -g
- 然后打开这个可执行文件 gdb app
- 然后按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