小型无人机系统试验规程
[toc]
[toc]
1 | ❯ docker run --restart=always -d --name holer-client -e PARAMS="www.swimminghao.top 6060 51c45156bf1c4a82b4e6ffff2150b65e" swimminghao/holer-client:latest |
1 | dockerfile1 |
1 | dockerfile2 |
dockerfile和jar包放同一文件夹,再执行下面指令
1 | ❯ docker build -t swimminghao/holer-client:latest . |
1 | FROM openjdk:8-jdk-alpine |
dockerfile和jar包放同一文件夹,再执行下面指令
1 | ❯ docker build -t swimminghao/holer-server:latest . |

1 | ❯ docker ps -a |
1 | ❯ docker history <83d576a828a8> --format "{{.CreatedBy}}" --no-trunc |tac | awk '{if($3~/nop/){for(i=1;i<=3;i++){$i=""};print substr($0,4)}else{print "RUN",$0}}' |
1 | ❯ bash decompile.sh seanhongxing/holer-server |
1 | #!/bin/bash |
1 | //镜像导出 |
注:分层,jar包在某一层
1. 本地修改了一堆文件(并没有使用git add到暂存区),想放弃修改。
单个文件/文件夹:
1 | $ git checkout -- filename |
所有文件/文件夹:
1 | $ git checkout . |
2. 本地新增了一堆文件(并没有git add到暂存区),想放弃修改。
单个文件/文件夹:
1 | $ rm filename / rm dir -rf |
所有文件/文件夹:
1 | $ git clean -xdf |
// 删除新增的文件,如果文件已经已经git add到暂存区,并不会删除!
3. 本地修改/新增了一堆文件,已经git add到暂存区,想放弃修改。
单个文件/文件夹:
1 | $ git reset HEAD filename |
所有文件/文件夹:
1 | $ git reset HEAD . |
4. 本地通过git add & git commit 之后,想要撤销此次commit
1 | $ git reset commit_id |
这个id是你想要回到的那个节点,可以通过git log查看,可以只选前6位
// 撤销之后,你所做的已经commit的修改还在工作区!
1 | $ git reset --hard commit_id |
这个id是你想要回到的那个节点,可以通过git log查看,可以只选前6位
// 撤销之后,你所做的已经commit的修改将会清除,仍在工作区/暂存区的代码不会清除!

workspace:工作区
Index/Stage:暂存区
Repository:仓库区(或本地仓库)
Remote:远程仓库
具体就是安装git-lfs,先下载,然后就是一顿操作:
先在web建立一个空仓库
然后建立跟仓库名一样的文件夹,并执行初始化命令:git init
然后执行git lfs install
然后添加你要上传的文件名或后缀名:git lfs track '*.zip'
然后就把生成的 .gitattributes文件,先传到远程仓库
git add .gitattributesgit commit -m 'large - init file'git push -u origin master:master # 第一次要这样执行,后面再传就git push就行。然后就可以正常添加上传大文件了!
git add bigfile.zipgit commit -m 'upload Big file.'git push # 第一次要这样执行,后面再传就git push就行。删除远程仓库文件,但本地文件不删除,如
1 | bigfile.zip |
git rm bigfile.zipgit commit -m 'rm bigfile.zip'git push
workspace:工作区
Index/Stage:暂存区
Repository:仓库区(或本地仓库)
Remote:远程仓库
1 | # 下载一个项目和它的整个代码历史 |
Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。
1 | # 显示当前的Git配置 |
1 | # 添加指定文件到暂存区 |
1 | # 提交暂存区到仓库区 |
1 | # 列出所有本地分支 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 # 显示有变更的文件
$ git status
# 显示当前分支的版本历史
$ git log
# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat
# 搜索提交历史,根据关键词
$ git log -S [keyword]
# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]
# 显示指定文件相关的每一次diff
$ git log -p [file]
# 显示过去5次提交
$ git log -5 --pretty --oneline
# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn
# 显示指定文件是什么人在什么时间修改过
$ git blame [file]
# 显示暂存区和工作区的差异
$ git diff
# 显示暂存区和上一个commit的差异
$ git diff --cached [file]
# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD
# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]
# 显示某次提交的元数据和内容变化
$ git show [commit]
# 显示某次提交发生变化的文件
$ git show --name-only [commit]
# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]
# 显示当前分支的最近几次提交
$ git reflog
1 | # 下载远程仓库的所有变动 |
1 | # 恢复暂存区的指定文件到工作区 |
项目开始的时候,项目发起者构建起一个项目的最原始的仓库,称之为源仓库(origin)。
如上所说,任何开发者都不会对源仓库进行直接的操作,源仓库建立以后,每个开发者需要fork一份源仓库,作为自己日常开发的仓库。
每个开发者所fork的仓库是完全独立的,互不干扰。每个开发者仓库相当于一个源仓库实体的镜像,开发者在这个镜像中进行编码,提交到自己的仓库中,这样就可以轻易地实现团队成员之间的并行开发工作。而开发工作完成以后,开发者可以向源仓库发送pull request,请求管理员把自己的代码合并到源仓库中,这样就实现了分布式开发工作,和最后的集中式的管理。
git分支有两类,5种:
1 | 永久性分支 |
1)clone远程代码
1 | git clone [url] |
2)切换到develop分支,将本地新项目提交到本地develop分支,再将本地develp分支上的新建项目将上传到远程develop分支。
1 | git checkout develop |
3)开发
切换到develop分支
1 | git checkout develop |
分出一个功能性分支
1 | git checkout -b function-branch |
在功能性分支上进行开发工作,多次commit,测试以后
把做好的功能合并到develop中
1 | git checkout develop |
4)合并远程master和develop分支
切换到master分支,从远程pull代码,将develop分支合并到本地master分支(此时本地master分支是与远程同步的),有冲突解决,没有则罢。最后push到远程master仓库。
(注)保证多人协作的时候尽量少出现merge conflict和污染主分支,做到以下几点:
做好分工,尽量避免出现多人修改同一个文件。
每个人的所有开发工作都只在自己的分支开发。
每个人只允许在自己的分支直接push远程分支。
合并的时候必须遵循以下条件.
1)首先本地切换到develop分支
1 | git checkout develop |
2)git pull
3)那么在pull到远程的develop最新的内容之后,
1 | git merge [branch] |
4)如果出现confict那么清除conflict之后,commit。然后把本地develop push到远程develop。
5)没完成一个功能就提交一次。不要累计代码。
git checkout dev
git push origin –delete release-1.00.00
1 | git clone |
1 | 正常上线 |
idea使用git通常需要忽略一些临时文件,需要配置.gitignore插件
安装插件
File -> Settings -> Plugins 搜索框搜索.ignore,点击安装
生成初始.ignore文件

出现如下弹框,会默认生成所选语言的常用忽略项,我这里选java,

生成如下文件
1 | # Compiled class file |
idea项目一般需要自己增加如下两项
1 | .idea/ |
即忽略这两个文件夹即文件夹下的所有文件
现在可以使用了,提交一次测试下
发现.idea文件夹下的文件还有变更被提交,这是因为在使用gitignore之前,此文件就以及被跟踪了,这样的话需要移除跟踪,如下命令:
移除指定文件夹即文件夹下所有文件:
1 | git rm --cached --force -r .idea |
移除指定文件:
1 | git rm --cached --force ydq-api/ydq-api.iml |
这样,表示移除成功。
现在,上面的操作进行提交:

移交移除文件.png
以后再做一些变更,当再次提交时,只有未被忽略的(被忽略的文件的变更再也不会被提交了)修改的文件了。
现在,idea下配置.gitignore结束。
注:
.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:
输入:
git rm -r –cached filePath
git commit -m “remove xx”
或者:
git rm -r –cached .
git add .
git commit -m “update .gitignore”
来解释下几个参数 -r 是删除文件夹及其子目录 –cached 是删除暂存区里的文件而不删除工作区里的文件,第一种是删除某个文件,第二种方法就把所有暂存区里的文件删了,再加一遍,相当于更新了一遍。
这个问题一定是最容易让人迷惑的,具体来说,就是搞不清什么时候用管道 符| 和文件重定向> ,< ,什么时候用变量$ 。
比如说,我现在有个自动连接宽带的 shell 脚本 connect.sh ,存在我的家目录:
1 | $ where connect.sh |
如果我想删除这个脚本,而且想少敲几次键盘,应该怎么操作呢?我曾经这
样尝试过:
1 | $ where connect.sh | rm |
实际上,这样操作是错误的,正确的做法应该是这样的:
1 | $ rm $(where connect.sh) |
前者试图将 where 的结果连接到 rm 的标准输入,后者试图将结果作为命令行参数传入。
标准输入就是编程语言中诸如 scanf 或者 readline 这种命令;而参数是指 程序的 main 函数传入的 args 字符数组。
前文「Linux文件描述符」说过,管道符和重定向符是将数据作为程序的标 准输入,而 $(cmd) 是读取 cmd 命令输出的数据作为参数。
用刚才的例子说, rm 命令源代码中肯定不接受标准输入,而是接收命令行 参数,删除相应的文件。作为对比, cat 命令是既接受标准输入,又接受 命令行参数:
1 | $ cat filename |
如果命令能够让终端阻塞,说明该命令接收标准输入,反之就是不接受,比 如你只运行 cat 命令不加任何参数,终端就会阻塞,等待你输入字符串并 回显相同的字符串。
比如说你远程登录到服务器上,运行一个 Django web 程序:
1 | $ python manager.py runserver 0.0.0.0 Listening on 0.0.0.0:8080... |
现在你可以通过服务器的 IP 地址测试 Django 服务,但是终端此时就阻塞 了,你输入什么都不响应,除非输入 Ctrl-C 或者 Ctrl-/ 终止 python 进程。
可以在命令之后加一个 & 符号,这样命令行不会阻塞,可以响应你后续输 入的命令,但是如果你退出服务器的登录,就不能访问该网⻚了。
如果你想在退出服务器之后仍然能够访问web服务,应该这样写命令 (cmd &) :
1 | $ (python manager.py runserver 0.0.0.0 &) Listening on 0.0.0.0:8080... |
底层原理是这样的:
每一个命令行终端都是一个 shell 进程,你在这个终端里执行的程序实际上 都是这个 shell 进程分出来的子进程。正常情况下,shell 进程会阻塞,等待 子进程退出才重新接收你输入的新的命令。加上 & 号,只是让 shell 进程不 再阻塞,可以继续响应你的新命令。但是无论如何,你如果关掉了这个 shell 命令行端口,依附于它的所有子进程都会退出。
而 (cmd &) 这样运行命令,则是将 cmd 命令挂到一个 systemd 系统守护进程名下,认 systemd 做爸爸,这样当你退出当前终端时,对于刚才的 cmd 命令就完全没有影响了。
类似的,还有一种后台运行常用的做法是这样:
1 | $ nohub some_cmd & |
nohub 命令也是类似的原理,不过通过我的测试,还是 (cmd &) 这种形式 更加稳定。
不同的 shell 行为会有细微区别,但有一点是确定的,对于 $ , ( , ) 这 几个符号,单引号包围的字符串不会做任何转义,双引号包围的字符串会转 义。
shell 的行为可以测试,使用 set -x 命令,会开启 shell 的命令回显,你可 以通过回显观察 shell 到底在执行什么命令:

可⻅ echo $(cmd) 和 echo “$(cmd)” ,结果差不多,但是仍然有区别。注 意观察,双引号转义完成的结果会自动增加单引号,而前者不会。
也就是说,如果 $ 读取出的参数字符串包含空格,应该用双引号括起来, 否则就会出错。
有时候我们普通用户可以用的命令,用 sudo 加权限之后却报错 command not found:
1 | $ connect.sh |
原因在于, connect.sh 这个脚本仅存在于该用户的环境变量中:
当使用 sudo 时,系统会使用 /etc/sudoers 这个文件中规定的该用户的权 限和环境变量,而这个脚本在 /etc/sudoers 环境变量目录中当然是找不到 的。
解决方法是使用脚本文件的路径,而不是仅仅通过脚本名称:
1 | $ sudo /home/fdl/bin/connect.sh |