linux-日常工作积累
Linux常用命令之envsubst
https://blog.csdn.net/banche163/article/details/101369495
Linux中的EAGAIN含义
https://blog.csdn.net/memo_weiwei/article/details/7691226
Linux中的虚拟设备/dev/null、/dev/zero、/dev/random和/dev/urandom
https://blog.csdn.net/sinat_26058371/article/details/86754683
修改系统时间,同步网络时间,修改时区:
https://www.cnblogs.com/suiyueshentou/p/7798340.html
https://my.oschina.net/qiongtaoli/blog/2051844
VMware虚拟机 Linux系统 Ubuntu 16.04 硬盘/磁盘扩容:
https://blog.csdn.net/m0_43403238/article/details/85480314?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
Clion on Ubuntu14.04, 无法使用Navigate中的Back命令的快捷键Ctrl+Alt+Left
https://segmentfault.com/q/1010000005040615
Linux 命令神器:lsof
https://www.jianshu.com/p/a3aa6b01b2e1
产生core文件: ulimit -c unlimited
基于gdb调试:gdb xx(如media-agent这是编译后的可执行文件) core,进入调试状态
gdb bt 可以看到比如coredump报错出现的问题,比如空指针,野指针,内存泄露
gdb f 1/2/3/4...
nohup 后台运行,进程查看以及终止:https://www.cnblogs.com/baby123/p/6477429.html
Linux MemFree与MemAvailable的区别
https://blog.51cto.com/xujpxm/1961072
linux命令行/shell 查看实时网速
LANG="" while true do up_time1=`ifconfig $1 | grep "bytes" | awk '{print $6}'` down_time1=`ifconfig $1 | grep "bytes" | awk '{print $2}'` sleep 1 clear up_time2=`ifconfig $1 | grep "bytes" | awk '{print $6}'` down_time2=`ifconfig $1 | grep "bytes" | awk '{print $2}'` up_time1=${up_time1} up_time2=${up_time2} down_time1=${down_time1} down_time2=${down_time2} up_time=`expr $up_time2 - $up_time1` down_time=`expr $down_time2 - $down_time1` up_time=`expr $up_time / 1024` down_time=`expr $down_time / 1024` echo 上传速度: $up_time kb/s echo 下载速度: $down_time kb/s done
Linux shell中2>&1的含义解释
https://blog.csdn.net/zhaominpro/article/details/82630528
deb格式
安装:
1、打开终端,执行命令:cd 文件所在目录,然后sudo dpkg -i 文件名.deb
2、执行命令:code(即文件名)然后文件就打开了,再然后右击图标锁定任务栏就可以了
卸载:
cd 文件目录,然后 dpkg -r 文件名.deb
打包成tar.gz格式压缩包
# tar -zcvf renwolesshel.tar.gz /renwolesshel
解压tar.gz格式压缩包
# tar zxvf renwolesshel.tar.gz
Linux下C语言串口通信
https://blog.csdn.net/continue_862/article/details/79919028
最近在做一个GPS项目,第一部分是将开发板和GPS用串口通信,接受GPS上传来的数据。 Linux下所有的设备都是以文件形式存储的,串口也是。 整个串口通信的流程图为: 所用到的头文件为: #include <stdio.h> #include <fcntl.h> #include <assert.h> #include <termios.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <sys/time.h> #include <sys/types.h> #include <errno.h> 用到了两个全局变量: static int fd; static int ret; 所需要的函数为: int uart_open(int fd,const char *pathname); int uart_config(int fd,int baude,int c_flow, int bits, char parity, int stop); int safe_read(int fd, char *vptr, size_t len); int uart_read(int fd, char *r_buf, size_t lenth);//串口读取数据 int uart_close(int fd); 打开串口: int uart_open() { assert(pathname);//检测串口路径是否存在 fd = open(pathname,O_RDWR|O_NTCCY|O_NDELAY);//以只读形式、不将此终端作为此进程的终端控制器、非阻塞的形式打开串口 if(fd == -1) { perror("uart open failed!"); return -1; } if(fcntl(fd,F_SETFL,0)<0)//设置串口非阻塞,因为这里是以非阻塞形式打开的,所以第三个参数为0,后面会详细介绍fcntl函数 { perror("fcntl failed!"); return -1; } return fd; } 配置串口: 配置串口非常重要,这里我做了一个配置串口函数的流程图 配置串口,就是设给termios结构体内的数据赋值,下面科普一下termios结构体 最小的termios结构体如下: struct termios{ tcflag_t c_iflag;//输入模式 tcflag_t c_oflag;//输出模式 tcflag_t c_cflag;//控制模式 tcflag_t c_lflag;//本地模式(也叫局部模式) cc_t c_cc[NCCS];//控制字符特性 } 输入模式和输出模式都比较好理解,这里介绍一下控制模式和本地模式 控制模式:主要用于控制终端设备的硬件设置。如:波特率,奇偶校验位,数据位,停止位,数据流控制等。 本地模式:主要用来控制终端设备不同的特色。如:回显的各种方式,是否允许特殊字符,禁止刷新等。 c_cc数组:特殊控制字元可提供使用者设定一些特殊的功能。 比如这里我们用到的c_cc[VTIME]设置等待时间,c_cc[VMIN]设置最小接受字符 用到的有关termios的函数: int tcgetattr(int fd, struct termios &termios_p);//用于获取termios结构体属性。成功返回0,失败返回非0 int tcsetattr(int fd, int actions, const struct termios *termios_p);//用于激活termios结构体配置 int fcntl(int fd, int cmd, long arg);//用来操作文件描述词的一些特性 返回值:成功返回0,失败返回-1,失败原因存入errno cmd有许多参数,可参考C函数库,这里用到的F_SETFL是设置文件描述词状态旗标,参数arg为新旗标 int tcflush(int fd, int queue_selector);//用于清空输入、输出缓冲区 //queue_selector有三种取值 TCIFLUSH(用于清空输入缓冲区) TCOFLUSH(用于清空输出缓冲区) TCIOFLUSH(用于清空输入输出缓冲区) 串口配置的函数代码: int uart_config(int fd,int baude,int c_flow, int bits, char parity, int stop); int uart_config(int fd,int baude,int c_flow, int bits, char parity, int stop) { struct termios uart; if(tcgetattr(fd,&uart)!=0) { perror("tcgetattr failed!"); return -1; } switch(baude) { case 4800: cfsetispeed(&uart,B4800);//设置输入波特率 cfsetospeed(&uart,B4800);//设置输出波特率 break; case 9600: cfsetispeed(&uart,B9600); cfsetospeed(&uart,B9600); break; case 19200: cfsetispeed(&uart,B19200); cfsetospeed(&uart,B19200); break; case 38400: cfsetispeed(&uart,B38400); cfsetospeed(&uart,B38400); break; default: fprintf(stderr,"Unknown baude!"); return -1; } switch(c_flow) { case 'N': case 'n': uart.c_cflag &= ~CRTSCTS;//不进行硬件流控制 break; case 'H': case 'h': uart.c_cflag |= CRTSCTS;//进行硬件流控制 break; case 'S': case 's': uart.c_cflag |= (IXON | IXOFF | IXANY);//进行软件流控制 break; default: fprintf(stderr,"Unknown c_cflag"); return -1; } switch(bits) { case 5: uart.c_cflag &= ~CSIZE;//屏蔽其他标志位 uart.c_cflag |= CS5;//数据位为5位 break; case 6: uart.c_cflag &= ~CSIZE; uart.c_cflag |= CS6; break; case 7: uart.c_cflag &= ~CSIZE; uart.c_cflag |= CS7; break; case 8: uart.c_cflag &= ~CSIZE; uart.c_cflag |= CS8; break; default: fprintf(stderr,"Unknown bits!"); return -1; } switch(parity) { case 'n': case 'N': uart.c_cflag &= ~PARENB;//PARENB:产生奇偶校验 uart.c_cflag &= ~INPCK;//INPCK:使奇偶校验起作用 break; case 's': case 'S': uart.c_cflag &= ~PARENB; uart.c_cflag &= ~CSTOPB;//使用两位停止位 break; case 'o': case 'O': uart.c_cflag |= PARENB; uart.c_cflag |= PARODD;//使用奇校验 uart.c_cflag |= INPCK; uart.c_cflag |= ISTRIP;//使字符串剥离第八个字符,即校验位 break; case 'e': case 'E': uart.c_cflag |= PARENB; uart.c_cflag &= ~PARODD;//非奇校验,即偶校验 uart.c_cflag |= INPCK; uart.c_cflag |= ISTRIP; break; default: fprintf(stderr,"Unknown parity!\n"); return -1; } switch(stop) { case 1: uart.c_cflag &= ~CSTOPB;//CSTOPB:使用两位停止位 break; case 2: uart.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unknown stop!\n"); return -1; } uart.c_oflag &= ~OPOST;//OPOST:表示数据经过处理后输出 if(tcsetattr(fd,TCSANOW,&uart)<0)//激活配置,失败返回-1 { return -1; } uart.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG );//使串口工作在原始模式下 uart.c_cc[VTIME] = 0;//设置等待时间为0 uart.c_cc[VMIN] = 1;//设置最小接受字符为1 tcflush(fd,TCIFLUSH);//清空输入缓冲区 if(tcsetattr(fd,TCSANOW,&uart)<0)//激活配置 { perror("tcgetattr failed!"); return -1; } return 0; } 接下来是安全读(防止内存溢出) 代码如下: int safe_read(int fd, char *vptr, size_t len) { size_t left; left = len; ssize_t nread; char *ptr; ptr = vptr; while(left > 0) { if ((nread = read(fd, ptr, left)) < 0) { if (errno == EINIR) { nread = 0; } else if(nread == 0) { break; } } left -= nread;//read成功后,剩余要读取的字节自减 ptr += nread;//指针向后移,避免后读到的字符覆盖先读到的字符 } return (len - left); } 然后是串口的读,这里主要是设置多路I/O,用到select函数 int uart_read(int fd, char *r_buf, size_t lenth); int uart_read(int fd, char *r_buf, size_t lenth) { fd_set rfds; struct timeval time; ssize_t cnt = 0; /*将读文件描述符加入描述符集合*/ FD_ZERO(&rfds); FD_SET(fd,&rfds); /*设置超时为15s*/ time.tv_sec = 15; time.tv_usec = 0; /*实现多路IO*/ ret = select(fd+1, &rfds ,NULL, NULL, &time); switch (ret) { case -1: fprintf(stderr,"select error!\n"); break; case 0: fprintf(stderr, "time over!\n"); break; default: cnt = safe_read(fd, r_rbuf, lenth); if(cnt == -1) { fprintf(stderr, "safe read failed!\n"); return -1; } return cnt; } } 最后一个函数是串口的关闭 int uart_close(int fd); int uart_close(int fd) { assert(fd);//assert先检查文件描述符是否存在 close(fd); return 0; } 最后是main函数 int main() { char r_buf[1024]; bzero(r_buf,1024); fd = uart_open(fd, "/dev/ttyS1");//选择的是ttsY1串口 if(fd == -1) { fprintf(stderr,"open failed!\n"); exit(EXIT_FAILURE); } if(uart_config(fd,4800,'N',8,'N',1) == -1) { fprintf(stderr,"configure failed!\n"); exit(EXIT_FAILURE); } while (1) { ret = uart_read(fd,r_buf,1024); if(ret == -1) { fprintf(stderr, "uart_read failed!\n"); exit(EXIT_FAILURE); } printf("buf:%s \n", r_buf); } ret = close(fd); if(ret == -1) { fprintf(stderr, "close failed!\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } arm-linux-gcc编译后,下载到开发板上运行,开发板连接GPS,所读到的数据: