@目录
linux基础命令
静态库 动态库
MakeFile 用法
GDB调试
Linux系统IO
打开和创建
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
//using namespace std;
int main() {
// int fd=open("a.txt",O_RDONLY);
// if (fd==-1){
// perror("open");
// }
// close(fd);
// return 0;
int fd=open("Create.txt",O_RDWR|O_CREAT,0777);
if (fd==-1){
perror("open");
}
close(fd);
return 0;
}
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);//打开一个已存在的文件
pathname:打开的文件路径
flags:文件的操作权限设置及其余相关设置 O_RDONLY, O_WRONLY, or O_RDWR.三个权限是互斥的
返回值:文件描述符 如果有错误则是-1
errno:属于linux系统函数库里的一个全局变量,记录最近的错误号
int open(const char *pathname, int flags, mode_t mode);//创建一个新的文件
pathname:创建的文件路径
flags:文件的操作权限设置及其余相关设置
必选 O_RDONLY, O_WRONLY, or O_RDWR.三个权限是互斥的 可选 O_APPEND O_ASYNC O_CLOEXEC O_CREAT O_DIRECTORY O_DSYNC O_EXCL O_LARGEFILE等等
int类型 四个字节 32位 每一位都是一个标志位
mode:八进制的数,新创建的文件的操作权限但是最后的权限是(mode & ~umask) 例子:0775 111111101 & 0777 111111111 =0775 111111101 即umask的作用是抹去权限
返回值:文件描述符 如果有错误则是-1
#include <stdio.h>
void perror(const char *s); //打印errno对应的错误描述
s:用户描述
返回值:用户描述+错误结果
#include <unistd.h>
int close(int fd);//关闭一个文件描述符
*/
读取和写入
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fdy=open("a.txt",O_RDONLY);
if (fdy==-1){
perror("open a.txt");
}
int fd=open("New.txt",O_WRONLY|O_CREAT,0664);
if (fd==-1){
perror("open New.txt");
}
char buf[1024]={0};
int len=read(fdy,buf,sizeof(buf));
while (len>0)
{
write(fd,buf,len);
len=read(fdy,buf,sizeof(buf));
}
close(fdy);
close(fd);
return 0;
}
/*
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);//读取文件
fd:文件描述符 通过open得到
buf:读取数据存放的地方,数组的地址(传出参数)
count:指定的数组大小
返回值:出现错误返回-1 成功>0返回读取到的字节数 =0表示文件读取结束
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);//写入数据
fd:文件描述符 通过open得到
buf:往磁盘写入的数据,数组的地址(传出参数)
count:写入数据的实际大小
返回值:出现错误返回-1 成功>0返回写入的字节数 =0表示文件写入结束
*/
lseek
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fdy=open("a.txt",O_RDWR);
if (fdy==-1){
perror("open a.txt");
}
int res=lseek(fdy,10,SEEK_END);
if (res==-1){
perror("lseek");
}
write(fdy," ",1);
close(fdy);
return 0;
}
/*
//linux系统函数
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);//1.移动文件指针2.获取当前文件指针的位置3.获取文件长度4.拓展文件的长度(需要写入一次文件才管用)
fd:文件描述符 通过open得到
offset: 偏移量
whence: 设置文件指针偏移量
SEEK_SET设置偏移量
SEEK_CUR当前位置加第二个参数offset的值
SEEK_END文件大小加第二个参数offset的值
返回值:返回文件指针的位置
c语言库函数
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
*/
获取文件相关信息
stat结构体的参数
st_mode变量
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
struct stat statbuff;
int res=stat("a.txt",&statbuff);
if (res==-1){
pause("stat");
return -1;
}
printf("size %ld\n",statbuff.st_size);
return 0;
}
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);//获取文件的一些相关信息
pathname:文件路基
statbuf:结构体变量,传出参数,用于保存获取到的文件信息
返回值:成功返回0 失败返回-1
int fstat(int fd, struct stat *statbuf);
pathname:文件路基
statbuf:结构体变量,传出参数,用于保存获取到的文件信息
返回值:成功返回0 失败返回-1
int lstat(const char *pathname, struct stat *statbuf);
*/
ls实现
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>>
//-rw-r--r-- 1 hws hws 94 Mar 25 15:35 New.txt
int main(int argc,char *agrv[]) {
if (argc<2){
printf("%s filename\n",agrv[0]);
return -1;
}
struct stat statbuff;
int res=stat(agrv[1],&statbuff);
if (res==-1){
perror("stat");
return -1;
}
char perm[11]={0};
switch (statbuff.st_mode& __S_IFMT)
{
case __S_IFLNK:
perm[0]='l';
break;
case __S_IFDIR:
perm[0]='d';
break;
case __S_IFREG:
perm[0]='-';
break;
case __S_IFBLK:
perm[0]='b';
break;
case __S_IFCHR:
perm[0]='c';
break;
case __S_IFSOCK:
perm[0]='s';
break;
case __S_IFIFO:
perm[0]='p';
break;
default:
perm[0]='?';
break;
}
perm[1]=(statbuff.st_mode&S_IRUSR)?'r':'-';
perm[2]=(statbuff.st_mode&S_IWUSR)?'w':'-';
perm[3]=(statbuff.st_mode&S_IXUSR)?'x':'-';
perm[4]=(statbuff.st_mode&S_IRGRP)?'r':'-';
perm[5]=(statbuff.st_mode&S_IWGRP)?'w':'-';
perm[6]=(statbuff.st_mode&S_IXGRP)?'x':'-';
perm[7]=(statbuff.st_mode&S_IROTH)?'r':'-';
perm[8]=(statbuff.st_mode&S_IWOTH)?'w':'-';
perm[9]=(statbuff.st_mode&S_IXOTH)?'x':'-';
int link_num=statbuff.st_nlink;
char *fileUser=getpwuid(statbuff.st_uid)->pw_name;
char *fileGrp=getgrgid(statbuff.st_gid)->gr_name;
long int fikesize=statbuff.st_size;
char *time =ctime(&statbuff.st_mtime);
char mtime[512]={0};
strncpy(mtime,time,strlen(time)-1);
char buf[1024];
sprintf(buf,"%s %d %s %s %ld %s %s",perm,link_num,fileUser,fileGrp,fikesize,mtime,agrv[1]);
printf("%s\n",buf);
return 0;
}
文件属性操作
access
/*
#include <unistd.h>
int access(const char *pathname, int mode);//判断某个文件是否有权限或者是否存在
pathname:文件路径
mode:R_OK, W_OK, X_OK,F_OK判断
返回值:成功返回0 失败返回-1
*/
#include <unistd.h>
#include<stdio.h>
int main(){
int ret=access("a.txt",F_OK);
if (ret==-1){
printf("文件不存在");
return -1;
}
printf("文件存在");
return 0;
}
chmod
/*
#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);//修改文件的权限
pathname:修改文件的路径
mode:需要修改的权限,八进制数字
返回值:成功返回0,失败返回1
int fchmod(int fd, mode_t mode);
*/
#include<stdio.h>
#include <sys/stat.h>
int main(){
int ret=chmod("a.txt",0775);
if (ret==-1){
perror("chmod");
return -1;
}
return 0;
}
chown
/*
#include <unistd.h>
int chown(const char *pathname, uid_t owner, gid_t group);//修改文件所有者和所有组
pathname:文件路径
owner:文件所有者id
group:文件所有组id
返回值:成功返回0,失败返回1
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *pathname, uid_t owner, gid_t group);
*/
获取当前系统下用户id和组id的命令
获取用户id结果获取组id结果
truncate
/* #include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);//缩小或拓展文件尺寸至指定大小
path:修改文件的路径
length:文件的最终大小
返回值:成功返回0 失败返回-1
int ftruncate(int fd, off_t length);
*/
#include <unistd.h>
#include <sys/types.h>
#include<stdio.h>
int main(){
int ret=truncate("a.txt",20);
if (ret==-1){
perror("truncate");
}
printf("拓展成功");
return 0;
}
目录操作
mkdir和redir和rename
/*
/*
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);//创建一个目录
pathname:创建目录的路径
mode:目录的权限
返回值:成功返回0 失败返回-1
*/
#include <sys/stat.h>
#include <sys/types.h>
#include<stdio.h>
int main(){
int ret=mkdir("aaa",0777);
if(ret==-1){
perror("mkdir");
return -1;
}
printf("创建目录成功");
return 0;
}
/*
#include <unistd.h>
int rmdir(const char *pathname);//删除目录(要求目录下没有文件否则会删除失败)
pathname 删除目录的路径
返回值 成功返回0 失败返回1
*/
/*
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);//重命名目录(要求目录下没有文件否则会失败)
oldpath 修改目录的路劲
newpath 新路径的路径
返回值 成功返回0 失败返回1
*/
chdir和getcwd
/*
#include <unistd.h>
int chdir(const char *path);//修改进程的工作目录
path:需要修改的工作目录、
返回值 成功返回0 失败返回1
int fchdir(int fd);
*/
/*
#include <unistd.h>
char *getcwd(char *buf, size_t size);//获取当前的工作目录
buf:存储的路径,指向一个数组(传出参数)
size:数组大小
返回值:指向一个地址,指向传入的buff数组
char *getwd(char *buf);
char *get_current_dir_name(void);
*/
#include <unistd.h>
#include<stdio.h>
int main(){
char buf[128];
getcwd(buf,sizeof(buf));
printf("当前工作目录是:%s\n",buf);
int ret=chdir("/home/hws/tt/l10");
if(ret==-1){
perror("chdir");
return -1;
}
char buf1[128];
getcwd(buf1,sizeof(buf1));
printf("当前工作目录是:%s\n",buf1);
return 0;
}
目录遍历函数
dirent的结构体
d_type的宏需要导入#define _GNU_SOURCE以获取
/*
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);/打开一个目录
name需要打开的目录
返回值:目录流信息失败返回Null
DIR *fdopendir(int fd);
*/
/*
#include <dirent.h>
struct dirent *readdir(DIR *dirp);//读取目录中的数据
dirp:通过opendir返回的结果
返回值:读取到的文件信息 读取到末尾或者失败了返回NUll
*/
/*
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);//关闭一个目录流
drip
*/
#define _GNU_SOURCE
#include <sys/types.h>
#include <dirent.h>
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include <errno.h>
int getFileNum(const char *path);
int main(int argc,char* argv[]){
if(argc<2){
printf("%s path\n",argv[0]);
return -1;
}
int res=getFileNum(argv[1]);
printf("普通文件的个数为%d",res);
return 0;
}
int getFileNum(const char *path){
DIR *dir=opendir(path);
if (dir==NULL){
perror("opendir");
return 0;
}
int res=0;
struct dirent *ptr;
while ((ptr=readdir(dir))!=NULL){
char *dname=ptr->d_name;
if(strcmp(dname,".")==0||strcmp(dname,"..")==0){
continue;
}
if(ptr->d_type==DT_DIR){
char newpath[256];
sprintf(newpath,"%s/%s",path,dname);
res+=getFileNum(newpath);
}
if(ptr->d_type==DT_REG){
res++;
}
}
closedir(dir);
return res;
}
dup和dup2
/*
#include <unistd.h>
int dup(int oldfd);//拷贝旧的文件描述符 将使用最小的文件描述符给新生成文件描述符
oldfd:需要拷贝的文件描述符
返回值:成功返回新的文件描述符 失败返回-1 两个文件描述符都指向同一个文件
int dup2(int oldfd, int newfd)//重定向文件描述符
例子:old—>a.txt new->b.txt 执行后new和b.txt做close 然后new->a.txt
返回值
*/
#include <unistd.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
// int main(){
// int fd=open("a.txt",O_RDWR|O_CREAT,0664);
// int fd1=dup(fd);
// if (fd1==-1){
// perror("dup");
// return -1;
// }
// printf("%d %d\n",fd,fd1);
// close(fd);
// char *srt="hello world";
// int ret=write(fd1,srt,strlen(srt));
// if (ret==-1){
// perror("write");
// return -1;
// }
// close(fd1);
// return 0;
// }
int main(){
int fd1=open("1.txt",O_RDWR|O_CREAT,0664);
if (fd1==-1){
perror("open");
return -1;
}
int fd2=open("2.txt",O_RDWR|O_CREAT,0664);
if (fd2==-1){
perror("open");
return -1;
}
printf("%d %d\n",fd1,fd2);
int fd3=dup2(fd1,fd2);
if (fd3==-1){
perror("open");`在这里插入代码片`
return -1;
}
char *srt="hello world";
int ret=write(fd2,srt,strlen(srt));
if (ret==-1){
perror("write");
return -1;
}
printf("%d %d %d\n",fd1,fd2,fd3);
close(fd2);
close(fd1);
return 0;
}
fcntl
/*
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... arg );1.复制文件描述符 2.获取和设置文件的状态
fd 需要操作的文件描述符
cmd 对文件描述符进行的操作
F_DUPFD复制文件描述符
F_GETFD获取文件描述符的状态(获取的状态和open函数传递flag相同)
F_SETFD设置文件描述符的状态(文件读写状态无法被修改,只能修改后面的比如O_APPEND表示追加数据 NONBLOK设置成非阻塞)
*/
#include <unistd.h>
#include <fcntl.h>
#include<stdio.h>
#include<string.h>
int main(){
int fd=open("1.txt",O_WRONLY);
if (fd==-1){
perror("open");
}
//复制文件描述符
int ret=fcntl(fd,F_DUPFD);
if (ret==-1){
perror("复制");
}
//修改文件描述符
int flag=fcntl(fd,F_GETFL);
if (flag==-1){
perror("获取");
}
ret=fcntl(fd,F_SETFL,flag|O_APPEND);
if (ret==-1){
perror("修改");
}
char *str ="yes";
ret=write(fd,str,strlen(str));
if (flag==-1){
perror("写入");
}
close(fd);
return 0;
}