常用工具指令

Git

从已提交的文件中删除文件,保留本地文件

git rm --cached

更改文件名

git mv file_from file_to

查看已add的文件与已提交的差别,若无–staged则为查看未add的文件与已提交文件的差别

git diff --staged

查看最近2个对文件修改的内容

git log -p -2

常用日志美化语句

git log --pretty=oneline
git log --pretty=format:"%h - %an, %ar : %s"
git log --pretty=format:"%h %s" --graph

覆盖上次commit

git commit --amend

取消对某文件的add

git restore --staged <filename>

取消本地对某文件的修改

git restore <filename>

分支相关命令

创建分支: git branch <branch-name>
创建远程分支: git push -u <shortname> <branch-name>
删除分支: git branch -d <branch-name>
删除远程仓库分支: git push <shortname> --delete <branch-name>
切换分支: git checkout <branch-name>

查看远程仓库信息

git remote -v

添加远程仓库

git remote add <shortname> <url>

删除远程仓库

git remote remove paul

连接本地git至github

当前github禁止使用密码进行登录,因此需要按如下步骤进行连接:

  1. 设置好Personal access tokens
  2. 使用git remote add <shortname> https://<token>@github.com/<github-name>/<repo-name>.git 添加远程仓库
  3. 使用git push --set-upstream/-u <shortname> <branch-name> 设置默认push/pull远程仓库

GDB

若想使用GDB进行代码调试则在使用GCC进行编译时需要使用-ggdb3选项。在Emacs中直接运行GDB需要使用M-x gdb指令。

  • start 开始程序的执行,在进入main函数后中止
  • run 运行程序
  • step 执行下一条指令,若当前指令对函数进行调用,则执行此函数的第一条指令
  • next 执行下一条指令,若当前指令对函数进行调用,则完全执行此函数
  • continue 继续运行程序
  • print 读取一个表达式作为参数,计算表达式的值并输出结果。每一次的print都会将当前值记下,并命名为\$1,\$2…。print使用@number语句输出数组中的多个元素,例如p a[0]@5将会输出a数组的前5个元素
  • display 读取一个表达式作为参数,并将在每一次提示用户输入前输出此表达式的值,缩写: disp
  • ENTER 重复执行上一条输入的GDB指令
  • backtrace 列出所有的栈帧,且最上方为当前函数,最下方为main函数,使用updown指令在栈中上下移动,缩写: bt
  • info 获取关于程序的各种信息,拥有许多子指令,如:info frame描述当前帧的内存结构,info types描述当前程序中的类型,info breakpoints描述断点状态等
  • break 设置程序断点,需要读取行号或函数名作为参数,将在此行或此函数的第一行设置断点,同时GDB为每一处断点分配一个值,用于与断点相关的其他操作,如cond。在Emacs中可以使用C-x C-a C-b来设置断点。
    同时break可以使用if指令进行条件型中断,如: break 7 if i==250000,条件型中断对于多循环语句的中断很有效。
  • cond 在断点已存在的情况下为其添加条件,如: cond 1 i==250000,意义为对断点1添加条件
  • enable disable delete 启用、禁用、删除断点
  • until 执行循环语句直到循环结束
  • finish 执行函数直到函数返回,缩写: fin
  • watch 设置观察点,需要读取一个表达式作为参数,将在此表达式的值发生改变时停止。同时可以利用print与watch指令对超出函数范围的表达式进行监视

每当程序接收到一个信号时GDB将会暂停程序,其中包括SIGSEGV、SIGABRT与SIGINT。

  • SIGSEGV 指示发生了段错误。当发生段错误时GDB将会停止在段错误发生的行
  • SIGABRT 当程序调用了abort()或assert结果错误时产生。
  • SIGINT 当程序被打断时产生,即用户使用Control-c中断了程序运行。当程序进入死循环时可以中断程序再利用GDB指令进行调试

make

在Makefile文件中包含使用先决条件(prerequisites)来产生目标文件(target)的规则,即如何从目标文件所依赖的文件中生成此目标文件。

当在命令行中使用make指令时能够指定所要创建的目标文件,若未指定则make将使用Makefile文件中第一个出现的目标文件作为默认目标文件。

myProgram: oneFile.o anotherFile.o
      gcc -o myProgram oneFile.o anotherFile.o
oneFile.o: oneFile.c oneHeader.h someHeader.h
      gcc -std=gnu99 -pedantic -Wall -c oneFile.c
anotherFile.o: anotherFile.c anotherHeader.h someHeader.h
      gcc -std=gnu99 -pedantic -Wall -c anotherFile.c

以上Makefile文件来自于AOP,以此为例进行说明

分号左侧为目标文件,右侧为先决条件文件,如要构建myProgram目标则需要确保已存在oneFile.o与anotherFile.o文件。make在构建目标文件时首先判断是否需要对先决文件进行更新,以oneFile.o为例,若oneFile.c的最新更新时间在oneFIle.o之后,则oneFile.o需要进行构建,在判断完毕后若myProgram不存在则直接进行构建,若已存在但最新更新时间在oneFile.o的最新更新时间之前则需要重新构建。同时在构建oneFile.o前make需要对其先决文件进行检查,若有任何一个先决文件不存在则停止编译。

基本使用技巧:

  • 变量 在Makefile文件中定义变量并利用\$()获取变量的值,例如:
CFLAGS=-std=gnu99 -pedantic -Wall
oneFile.o: oneFile.c oneHeader.h someHeader.h
      gcc $(CFLAGS) -c oneFile.c
  • clean目标 clean目标的创建需要定义所要删除的文件,如编译结果文件等,则使用make clean将会删除所指定的文件,例如:
.PHONY: clean
clean:
      rm -f myProgram *.o *.c~ *.h~

其中.PHONY: clean指定clean为假目标,即不需要创建clean文件,也不需要对其进行更新检查等

CFLAGS=-std=gnu99 -pedantic -Wall
myProgram: oneFile.o anotherFile.o
      gcc -o myProgram oneFile.o anotherFile.o
%.o: %.c
      gcc $(CFLAGS) -c $<
.PHONY: clean
clean:
      rm -f myProgram *.o *.c~ *.h~
oneFile.o: oneHeader.h someHeader.h
anotherFile.o: anotherHeader.h someHeader.h

重复的….o: ….c可以由%.o: %.c进行替代,其中%.c文件名将与%.o相同,make会将\$<设置为第一个先决文件,即.c文件。由于利用%.o: %.c方式无法添加所依赖的.h文件,因此利用最后两行语句为目标添加依赖信息,因为最后两行未指定所使用的指令,因此make将其视作附加依赖信息而不会取代已存在的编译指令

make内置的配置选项包含了常用的编译规则,可以使用make -p查看所有的规则,因此可以通过修改内置规则的部分变量从而简化Makefile的编写。其中内置规则例如:

%.o: %.c
       $(COMPILE.c) $(OUTPUT_OPTION) $<
#...
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
OUTPUT_OPTION = -o $@
# $@指当前目标名称

简化后的Makefile例如:

CC = gcc
CFLAGS=-std=gnu99 -pedantic -Wall
myProgram: oneFile.o anotherFile.o
      gcc -o myProgram oneFile.o anotherFile.o
.PHONY: clean depend
clean:
      rm -f myProgram *.o *.c~ *.h~
depend:
      makedepend anotherFile.c oneFile.c

makedepend能够自动生成.c文件所依赖的头文件,因此使用make depend指令能够在Makefile文件内自动写入目标所需要的附加依赖信息

make支持并行编译,使用-j选项使得make尽可能多地并行编译,同时可以加上数字为并行编译任务数设置上限,如make -j8

内置函数

make具有内置函数,调用语法为\$(functionName arg1, arg2, arg3)

  • \$(wildcard pattern) 从当前文件夹中找到符合pattern的文件,例: SRCS=$(wildcard *.c)
  • \$(patsubst pattern, replacement, text) 将text符合pattern的部分替换为replacement,例: OBJS=$(patsubst %.c, %.o, $(SRCS))

利用上述两个函数可以得到如下Makefile文件:

CC = gcc
CFLAGS=-std=gnu99 -pedantic -Wall
SRCS=$(wildcard *.c)
OBJS=$(patsubst %.c, %.o, $(SRCS))
myProgram: $(OBJS)
      gcc -o $@ $(OBJS)
.PHONY: clean depend
clean:
      rm -f myProgram *.o *.c~ *.h~
depend:
      makedepend $(SRCS)

生成Debug版本

CC = gcc
CFLAGS=-std=gnu99 -pedantic -Wall -o3
DBGFLAGS=-std=gnu99 -pedantic -Wall -ggdb3 -DDEBUG
SRCS=$(wildcard *.c)
OBJS=$(patsubst %.c, %.o, $(SRCS))
DBGOBJS=$(patsubst %.c, %.dbg.o, $(SRCS))
.PHONY: clean depend all
all: myProgram myProgram-debug
myProgram: $(OBJS)
      gcc -o $@ -o3 $(OBJS)
myProgram-debug: $(DBGOBJS)
      gcc -o $@ -ggdb3 $(DBGOBJS)
%.dbg.o: %.c
      gcc $(DBGFLAGS) -c -o $@ $<
clean:
      rm -f myProgram myProgram-debug *.o *.c~ *.h~
depend:
      makedepend $(SRCS)
      makedepend -a -o .dbg.o $(SRCS)

Docker

常用指令

  • docker images
    Show the list of images
  • docker run --name <container name> -p <local port>:<container port> -d <image name>
    Instantiate a container by the image and run, the first port is the port mapping to the second port, which is the port exposed by the container. -d means terminal detaches from the process.
  • docker ps -a
    Check the list of running containers. -a means show the whole list, not only the running ones.
  • docker stop <container name>
    Stop the running container
  • docker start <container name>
    Start the existing but not running container.
  • docker build -t <image name>(:image tag) <relative path to Dockerfile>
    Create the image by Dockerfile
  • docker image rm <image name>
    Remove the specific image
  • docker container rm <container name>
    Remove the specific container
  • docker system prune -a
    Clear all in the docker
  • docker-compose up
    Find the docker-compose.yaml file in the current path and create composed containers.
  • docker-compose down --rmi all -v
    Stop and delete the containers, –rmi all means remove all images, -v means remove all volumes created by docker-compose.

Dockerfile

FROM node:17-alpine  
#load specific image

WORKDIR /app 
#set working dirctory for the following instructions

COPY package.json .
#copy package.json in case of installing modules again when revising source files

RUN npm install 
#run npm install instruction to install the dependencies

COPY . . 
#copy current files in the current dirctory to /app/. in the container

EXPOSE 4000 
#expose port 4000

CMD ["node", "app.js"] 
#run node app.js after finishing creating the container

Use the .dockerignore file to ignore specific files in the path in the COPY instruction.

docker-compose.yaml

version: "3.8"
services:
    api:
        build: ./api
        container_name: api_c
        ports:
            - '4000:4000'
        volumes:
            - ./api: /app
            - /app/node_modules
version: "3.8"
services:
  redis:
    image: redis:7.0.7-bullseye
    container_name: redis_c
    ports:
      - '6379:6379'
    command: redis-server /usr/local/etc/redis/redis.conf
    volumes:
      - ./redis/redis.conf:/usr/local/etc/redis/redis.conf
      - ./redis/data:/data
  ass:
    build: ./ass
    container_name: ass_c
    ports:
      - '6677:6677'
    volumes:
      - ./ass:/ass
    stdin_open: true
    tty: true

create docker development environment

  1. 在本地创建初始目录结构,即Dockerfile及所要开发项目的初始代码
  2. 创建基于上述Dockerfile的image
  3. 使用类似下列语句实例化container
    docker run -dit --rm -v ${PWD}:/app --name app_c -p 3000:3000 app:v1
    -d 表示后台运行,-it 表示命令行方式运行,–rm 表示一旦实例stop则删除实例,-v 将本地${PWD}目录与container中的/app目录进行映射,则本地对文件的修改将同步至container内
  4. 由于本地目录与container路径同步,因此可以在本地进行代码编辑,进入container内执行代码,从而完成开发过程
  5. 开发完毕后stop container,重新创建image,上传至docker hub

多容器通信

  1. 创建名为redis-net的网络
    docker network create redis-net
  2. 运行 Redis 在redis-net网络中,别名redis
    docker run -d --name redis --network redis-net --network-alias redis redis:latest
  3. 修改代码中访问redis的地址为网络别名
    url: redis://redis:6379
  4. 使用同一网络运行web
    docker run -p 8080:8080 --name test -v D:/test:/app --network redis-net -d test:v1

nginx允许跨域访问:add_header Access-Control-Allow-Origin *;
注:跨域访问不允许传输json数据,需要以plain/text形式进行传输

Ubuntu更新kernel version

  • uname -r
  • apt-get install Linux 5.4.0-104-generic
  • Edit /etc/default/grub file. Find GRUB_DEFAULT and specify path to the grub menu entry (something like GRUB_DEFAULT='Advanced options for Ubuntu>Ubuntu, with Linux 5.4.0-104-generic')
  • sudo update-grub
  • sudo reboot
  • sudo apt-get update && sudo apt-get install linux-headers-5.4.0-104-generic

Related post

  1. Golang入门

    2024-02-04

  2. Windows下ARM编程实验

    2020-11-29

  3. Java 容器

    2020-08-03

  4. 将python脚本挂至服务器后台自动运行

    2020-07-05

There are no comment yet.

COMMENT

Take a Coffee Break

Recommend post

  1. 常用工具指令

    2022-09-18

Category list

ABOUT

Welcome to FullStar, a captivating online destination where the realms of software development and personal reflections intertwine.

April 2025
M T W T F S S
 123456
78910111213
14151617181920
21222324252627
282930  

Life Logs

  1. 回首

    2023-07-14

Return Top