• Linux-02


    vimtutor

    vimtutor (小写的)进入学习教程,这是英文版本的

    vimtutor zh_CN这个进入是中文版本的

    1567490981319

    :set nu (冒号 set nu)显示行号

    1. hjkl 光标左下上右移动,w下个单词,b上个单词

    2. :q! (冒号q感叹号)不保存退出

    3. x 删除指定位置字母

    4. 小写i进入编辑,esc退出,从光标当前位置开始添加 大写I行首

    5. a进入编辑,esc退出,从光标右边开始添加,大写A行尾

    6. 控制台输入 vim 文件名,可以进入编辑代码状态,通过插入编辑完之后,用:wq保存退出。

      当前文件夹就可以保存刚刚输入的内容。

    7. 直接在要删除的词上面 dw (无回显) 删除一个词

    8. d$删除至末尾 d~删除至行首 dG删除至文档尾,d1G删除到文档首

    9. 0到行首,w到下个字母首,e到下个字母尾、

    10. d2w删除2个单词

    11. 2dd删除2行

    12. u撤销一下,大写U恢复该行修改前,Ctrl+R恢复被撤销

    13. dd先删除(其实是剪切),ecx退出之后用p命令在光标所在位置会粘贴刚刚dd删除的内容

    14. 光标移动到要修改字母的位置,输入r再输入想要的字母就可以替换

    15. cw修改一个词错误的地方(会自动帮忙删除光标所在位置到词尾)

    16. c$整行

    17. 大写G到文件最后一行,小写gg到文件第一行,CTRL+G会显示当前行号,行号(无回显)+G跳转到行号的位置

    18. /字符串,向下找字符串。之后,按小写“n”是再来一次

      ?字符串 ,向上找字符串。之后,按大写“N”是再来一次

      Ctrl+o回到未跳之前光标

      Ctrl+i相对ctrl+o

    19. % 放匹配符号上(括号等)会自动匹配

    20. 在一行内替换头一个字符串 old 为新的字符串 new,请输入 :s/old/new 在一行内替换所有的字符串 old 为新的字符串 new,请输入 :s/old/new/g 在两行内替换所有的字符串 old 为新的字符串 new,请输入 :#,#s/old/new/g 在文件内替换所有的字符串 old 为新的字符串 new,请输入 :%s/old/new/g 进行全文替换时询问用户确认每个替换需添加 c 标志 :%s/old/new/gc

    21. 在写代码的时候,直接输入:外部命令。可以直接使用外部的命令

      1567494865913

    22. : w test 保存文件 saveas 另存为

    23. 部分保存:移动到某个位置。然后按v会进入高亮显示。然后选择的内容:w test保存起来。

    24. 读取文件内容,跟保存操作一样

    25. 输入小写o在光标所在行下面开始输入,大写O在上面

    26. 大写R。连续替换

    27. v配合y复制。然后再p粘贴

    28. :set hls is高亮,:nohlsearch取消高亮

    29. 输入 :set xxx 可以设置 xxx 选项。一些有用的选项如下: 'ic' 'ignorecase' 查找时忽略字母大小写 'is' 'incsearch' 查找短语时显示部分匹配 'hls' 'hlsearch' 高亮显示所有的匹配短语

    30. Vim 的功能特性要比 Vi 多得多,但其中大部分都没有缺省启用。为了使用更多的 特性,您得创建一个 vimrc 文件。

      1. 开始编辑 vimrc 文件,具体命令取决于您所使用的操作系统: :edit ~/.vimrc 这是 Unix 系统所使用的命令 :edit $VIM/_vimrc 这是 MS-Windows 系统所使用的命令

      2. 接着读取 vimrc 示例文件的内容: :r $VIMRUNTIME/vimrc_example.vim

      3. 保存文件,命令为: :write

      下次您启动 Vim 时,编辑器就会有了语法高亮的功能。 您可以把您喜欢的各种设置添加到这个 vimrc 文件中。 要了解更多信息请输入 :help vimrc-intro

    31. 输入一个字母。ctrl+D会显示可以补全的。然后tab可以选择不全的那个单词

    GCC/G++

    c/c++语言的编译器

    • -o : 指定生成的文件的名字

    • -S -masm=intel : 生成源文件对应的汇编文件(使用intel格式的汇编)

    • -m32 : 编译成32为的程序

    • -c : 只编译不链接

    • -static : 静态编译

    • -share : 动态编译

    • -shared : 编译成共享库(so文件,就是动态链接库)

    • -g : 生成调试信息

    fun.c

    #include <stdio.h>
    int fun()
    {printf("fun ");}

    main.c

    #include <stdio.h>
    int fun();
    int main()
    {printf("hello world ");
    fun();}

    输入gcc main.c fun.c -o hello 生成hello文件 输入 ./hello 运行

    1567497100394

    跟C语言对比的话,默认就是直接导出函数,加了static的不导出。

    make

    make是一个源码组织工具(组织项目的编译链接)

    它使用Makefile来描述一个项目的编译和链接方法

    Makefile的规则:

    目标 : 依赖项
    生成命令

    执行流程:
    1. 检查目标是否存在.
    2. 如果不存在则检查依赖项是否存在.
    3. 如果依赖项存在, 则调用生产命令来通过依赖项生成目标.
    4. 如果依赖项不存在, 则将依赖项作为目标向下扫描文件内容,找到生成方法.

    例如:

    a.out : main.o fun.o
       gcc main.o fun.o -o a.out

    main.o : main.c
    gcc main.c -c -o main.o

    fun.o : fun.c
    gcc fun.c -c -o fun.o

    clean:
    rm *.o a.out

    使用Makefile的时候, 只需要在Makefile文件所在的目录下执行make命令即可. 执行make命令的时候, 也可以通过命令行参数,来指定生成哪个目标: make clean

    高级make工具

    make工具对于项目源码组织已经目录复杂项目的要求了.

    当前已经有了很多更简单, 更强大的make工具, 这些工具原理实际还是根据一些脚本自动生成Makefile ,最后调用make来执行Makefile脚本.

    这些工具有: automake , qmake , cmake

    gdb

    调试器

    开始调试

    gdb 被调试的文件路径

    开始调试的时候, 如果希望能够进行源码调试, 需要编译程序时, 加上-g选项

    gcc main.c fun.c -o hello -g

    常用命令

    1. 运行

      1. r - 直接运行程序

      2. s/n 源码级别的单步步入/单步步过

      3. c 继续运行

      4. si/ni 汇编级别的单步步入/单步步过

    2. 断点设置

      1. b 函数名/行号/*地址

        1. 注意, 如果是一个地址,需要加上*

    3. 信息查看

      1. 查看反汇编 : disassemble

        1. 设置反汇编的格式: `set disassembly-flavor intel

      2. 查看断点: i b

      3. 查看变量的值: print 变量名

      4. 查看内存: x /10bx 地址

        1. 10总共显示10个单位

        2. b表示按字节显示, w按字显示, d按双字显示

        3. x表示以16进制显示, d表示以十进制显示

      5. layout

        1. layout src 查看源码

        2. layout split 查看源码和汇编

    改阿里源为Ubuntu 18.04默认的源

    备份/etc/apt/sources.list #备份 cp /etc/apt/sources.list /etc/apt/sources.list.bak

    在/etc/apt/sources.list文件前面添加如下条目 #添加阿里源 deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse

    最后执行如下命令更新源 ##更新 sudo apt-get update sudo apt-get upgrade

    SSH

    sudo apt install openssh-server

    安装步骤 按照如下安装步骤进行安装

    步骤 命令 说明 步骤1 sudo su 切换至root用户,ubuntu缺省下root用户有所限制,使用sudo su可以使用当前管理用户的密码切换至root用户,也可以在需要安装权限的命令前加sudo 步骤2 apt install openssh-server 安装openssh-server 步骤3 ssh -V 确认openssh-server版本 步骤4 /etc/init.d/ssh status 确认openssh-server状态 步骤5 /etc/init.d/ssh restart 重新启动 openssh-server 步骤6 从终端使用ssh命令连接确认 步骤7 ifconfig 查看IP地址,用来VS建立调试用。

    vs创建linux项目

    Visual Studio Installer

    修改

    使用C++的Linux开发

    新建项目-跨平台-linux

    1567511744041

    1567511828358

    F5运行生成后。再虚拟机这个位置可以找到生成的文件

    ubuntu@vmware-machine:~/projects/Project1/bin/x64/Debug

    1567511918332

    PROC

    步骤一cd /proc

    步骤二 ls 查看下有什么进程

    步骤三cd 进程ID就能进入进程

    如何查看源代码

    步骤一 which ps

    步骤二 dpkg -S /bin/ps

    步骤三 sudo apt-get source procps

    (过程安装了这个)sudo apt-get install dpkg-dev

    成功后会自动下载到

    /home/ubuntu

    1567526318268

    下载Linux命令的源码

    1. 获取命令的路径: which 命令名, 例如: which ps

      1. 一般会的到命令的文件路径:

    2. 使用dpkg -S 命令的路径获取命令源码包

    3. 使用sudo apt source 源码包名 下载源码包

    CLION

    步骤一 file-open-打开刚刚下载的源文件夹

    步骤二 edit-find-find in path

    输入List of process IDs must follow --pid()

    1567528006391

    1567528293136

    步骤四,根据关键字找到相关函数

    步骤五,根据函数名右键-Find Usages找到main函数,然后进去分析。

    1567528416439

    使用共享库

    1. 编译共享库

      1. gcc 的编译选项: -FPIC -shared

        `gcc -fPIC -shared testso.c -o libtestso.so

      2. 生成的文件, 必须以lib开头, 必须以.so结尾, 有些时候, 文件后缀中会出现一些数字, 这些数字其实是so文件版本号

    2. 在共享库中导出函数

      1. 在源码中, 没有加static函数都是默认被导出的

    3. 在其他工程中调用共享库的导出函数

      1. 声明函数原型

      2. 直接调用

      3. 在编译时, 需要指定链接对应的so文件

        1. 使用-L选项来指定so所在的目录

        2. 使用-l选项来指定要连接的so文件的名字(名字不能加上libso后缀)

          例如: gcc -L/usr/lib -ltestso main.c

      4. 将so文件拷贝到/usr/lib目录, 否则程序运行时是找不到这个so文件的.

    Linux编程

    文件操作

    遍历文件

    void enum_file(const char* dir_name)
    {
        DIR* dir = opendir("/home/ez");
        struct dirent* ent;
        while( ent = readdir(dir))
       {

            if(strcmp(ent->d_name,".") == 0
            || strcmp(ent->d_name,"..")==0)
           {
                continue;
           }

            if(ent->d_type & 4){
                // 文件夹
                // 递归遍历
                char buff[266];
                sprintf(buff,"%s/%s",dir_name,ent->d_name);
                //printf("buff=%s ",buff);
                // enum_file(buff);
           }
            printf("%s %08X ", ent->d_name, ent->d_type);
       }
        closedir(dir);
    }

    进程操作

    1进程遍历

    #include <iostream>
    #include <dirent.h>
    #include <cstring>

    int main() {
        // 遍历进程
        DIR *dir = opendir("/proc");
        if(dir == NULL){
            printf("打开目录失败,错误:%s ",
                    strerror(errno));
            return 0;
       }
        struct dirent *ent = NULL;
        while (ent = readdir(dir)) {
            if (ent->d_name[0] < '1'
                || ent->d_name[0] > '9') {
                continue;
           }
            char buff[266];
            sprintf(buff, "/proc/%s/status",
                    ent->d_name);
            FILE *f = fopen(buff, "r");
            if(f == NULL){
                printf("打开文件失败,错误:%s ",
                       strerror(errno));
                continue;
           }
            fscanf(f, "Name: %s", buff);
            printf("pid=%s name=%s ",
                   ent->d_name,
                   buff);

            fclose(f);

       }
        return 0;
    }

    读写其它进程的内存

    windows : ReadProcMemory/WriteProcMemory

    linux : 以读写文件的方式,读写内存

    /proc/XX/mem 该文件是不能直接查看, 这个文件是代表一个进程的虚拟内存. 如果修改了这个文件内容, 那么对应的进程的内存也会被直接修改. 读取文件的内容, 其实就读取出进程的内存.

    #include <cstdio>
    #include <unistd.h>
    #include <string.h>
    #include <fcntl.h>

    int main()
    {
    int pid;
    char* p = NULL;
    printf("请输入PID:");
    scanf("%d", &pid);

    printf("请输入要修改的内存地址:");
    scanf("%p", &p);
    printf("请输入修改的内存数据:");
    char buff[100];
    scanf("%s", buff);

    // 开始修改
    // 修改/proc/pid/mem的文件就相当于修改了内存
    char path[266];
    sprintf(path, "/proc/%d/mem", pid);
    int fd = open(path, O_CREAT|O_RDWR, 0);

    // 读取出原始的内存
    //1. 设置文件读写位置
    lseek64(fd,(__off64_t)p, SEEK_SET);
    read(fd, path, 100);
    printf("%p : %s ", p, path);

    lseek64(fd, (__off64_t)p, SEEK_SET);
    write(fd, buff, strlen(buff) + 1);
    printf("写入完毕 ");
    close(fd);

        return 0;
    }

    进程创建

    execl(char* path) - 在当前进程中运行一个可执行程序. 函数不会创建新的进程, 而是将路径中指定的可执行程序直接加载到本进程的空间, 覆盖掉调用者的进程. 从而去运行新的代码(实际就是新的进程)

    fork - 创建一个新的进程, 但是新的进程代码是完全拷贝自身的.

    创建新进程:

    int pid = fork();
    if(pid == -1){ // 如果是子进程,函数会返回-1, 如果是父进程,函数返回是子进程的pid
    execl("新进程的路径");
    return 0;
    }

    ptrace 函数和调试有关

  • 相关阅读:
    QPS、PV和需要部署机器数量计算公式
    libevent 源码深度剖析十三
    libevent源码深度剖析十二
    libevent源码深度剖析十一
    libevent源码深度剖析十
    libevent源码深度剖析九
    libevent源码深度剖析八
    ADO.NET入门教程(三) 连接字符串,你小觑了吗?
    配置文件的使用,如果要跨平台,建议直接用 xml, json, ini 或者本文档,看自己方便
    firemonkey 去掉ios 虚拟键盘上的‘done’toolbar
  • 原文地址:https://www.cnblogs.com/ltyandy/p/11456643.html
Copyright © 2020-2023  润新知