解决拉取github仓库报错“gnutls_handshake() failed”问题

本文首发于:https://blog.frytea.com/archives/421/

gnutls_handshake() failed: The TLS connection was non-properly terminated.

最近为新配置的虚机拉取库,但是从 GitHub 拉取库总是出问题,查阅网上文献将问题锁定在代理,但是找了一圈还是没有找到答案。

经过仔细排查,发现还是由于代理设置有错,为 http 错误配置了 https 的代理,导致出错。

如果没有配置代理,可使用以下命令 取消代理

git config --global --unset http.proxy
git config --global --unset https.proxy

如果需要使用 代理http 协议通过以下命令配置,使用 7890 端口为例:

git config --global http.https://github.com.proxy http://127.0.0.1:7890
git config --global https.https://github.com.proxy https://127.0.0.1:7890

socket 协议通过以下命令配置,使用 7890 端口为例:

git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'

也可以这样子 仅代理 GitHub

git config --global http.https://github.com.proxy socks5://127.0.0.1:1080
#取消代理
git config --global --unset http.https://github.com.proxy

拓展阅读

Vim安装插件管理器Vundle

安装vundle

$ git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

默认安装在/.vim/bundle/vundle下;

配置说明:

插件有三种类型:

  1. Github上vim-scripts仓库的插件
  2. Github上非vim-scripts仓库的插件
  3. 不在Github上的插件 对于不同的插件,vundle自动管理和下载插件的时候,有不同的地址填写方法,有如下三类:
  1. 在Github上vim-scripts用户下的仓库,只需要写出repos(仓库)名称
  2. 在Github其他用户下的repos, 需要写出”用户名/repos名”
  3. 不在Github上的插件,需要写出git全路径

配置vundle插件:

可以在终端通过vim打开~/.vimrc文件,

$ vim ~/.vimrc

将以下加在.vimrc文件中,加入之后保存之后就可以使用vundle了。

添加的配置信息(样例)注:以后安装新插件就直接编辑vimrc,添加plugin就行了,在这里我们添加的plugin只是例子,你可以不安装这些插件,换上自己需要安装的插件。

set nocompatible              " 去除VI一致性,必须要添加
filetype off                  " 必须要添加

" 设置包括vundle和初始化相关的runtime path
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" 另一种选择, 指定一个vundle安装插件的路径
"call vundle#begin('~/some/path/here')

" 让vundle管理插件版本,必须
Plugin 'VundleVim/Vundle.vim'

" 以下范例用来支持不同格式的插件安装.
" 请将安装插件的命令放在vundle#begin和vundle#end之间.
" Github上的插件
" 格式为 Plugin '用户名/插件仓库名'
Plugin 'tpope/vim-fugitive'
" 来自 http://vim-scripts.org/vim/scripts.html 的插件
" Plugin '插件名称' 实际上是 Plugin 'vim-scripts/插件仓库名' 只是此处的用户名可以省略
Plugin 'L9'
" 由Git支持但不再github上的插件仓库 Plugin 'git clone 后面的地址'
Plugin 'git://git.wincent.com/command-t.git'
" 本地的Git仓库(例如自己的插件) Plugin 'file:///+本地插件仓库绝对路径'
Plugin 'file:///home/gmarik/path/to/plugin'
" 插件在仓库的子目录中.
" 正确指定路径用以设置runtimepath. 以下范例插件在sparkup/vim目录下
Plugin 'rstacruz/sparkup', {'rtp': 'vim/'}
" 安装L9,如果已经安装过这个插件,可利用以下格式避免命名冲突
Plugin 'ascenator/L9', {'name': 'newL9'}

" 你的所有插件需要在下面这行之前
call vundle#end()            " 必须
filetype plugin indent on    " 必须 加载vim自带和插件相应的语法和文件类型相关脚本
" 忽视插件改变缩进,可以使用以下替代:
"filetype plugin on
"
" 常用的命令
" :PluginList       - 列出所有已配置的插件
" :PluginInstall     - 安装插件,追加 `!` 用以更新或使用 :PluginUpdate
" :PluginSearch foo - 搜索 foo ; 追加 `!` 清除本地缓存
" :PluginClean      - 清除未使用插件,需要确认; 追加 `!` 自动批准移除未使用插件
"
" 查阅 :h vundle 获取更多细节和wiki以及FAQ
" 将你自己对非插件片段放在这行之后

安装需要的插件

  1. 将想要安装的插件,按照地址填写方法,将地址填写在vundle#beginvundle#end之间就可以
  2. 保存之后,有两种方法安装插件。

(1) 运行 vim ,再运行 :PluginInstall

$vim
:PlugInstall

(2) 通过命令行直接安装 vim +PluginInstall +qall

vim +PluginInstall +qall

安装完成之后,插件就可以使用。

移除不需要的插件

  1. 编辑.vimrc文件移除的你要移除的插件所对应的plugin那一行。
  2. 保存退出当前的vim
  3. 重新打开vim,输入命令BundleClean

其他常用命令

  1. 更新插件BundleUpdate
  2. 列出所有插件BundleList
  3. 查找插件BundleSearch

参考文献

Ubuntu下为vim安装YouCompleteMe插件

前提条件

安装

第一步,使用Vundle安装YouCompleteM

在.vimrc中添加以下内容

Plugin 'Valloric/YouCompleteMe'

然后拉取源码(或是 :PluginInstall 也可)

$ cd ~/.vim/bundle
#./install.py需要克隆,不能直接下载zip压缩包
$ git clone https://github.com/Valloric/YouCompleteMe.git

第二步,拉取依赖(包括可能用到的工具)

$ cd YouCompleteMe
$ git submodule update --init --recursive
$ sudo apt install cmake
$ sudo apt install clang
$ sudo apt-get install python3-dev

第三步,安装代码提示

# 仅安装支持Python的版本:
$ ./install.py

# 安装支持C语言家族的版本:
$ ./install.py --clang-completer

# 安装支持go语言的版本:
$ ./install.py --go-completer

# 安装支持Js、Java、Python、go所有语言的版本:
$ ./install.py --all

第四步,添加.vimrc配置

$ vim .vimrc
let g:ycm_global_ycm_extra_conf='~/.vim/.ycm_extra_conf.py'

第五步,测试

[]()

参考文献

VIM 创建程序文件自动添加头部注释

修改 /etc/vimrc~/.vimrc,在文件最后添加以下内容:

" 当新建 .h .c .hpp .cpp .mk .sh等文件时自动调用SetTitle 函数
autocmd BufNewFile *.[ch],*.hpp,*.cpp,Makefile,*.mk,*.sh exec ":call SetTitle()"
" 加入注释 
func SetComment()
        call setline(1,"/*================================================================")
        call append(line("."),   "*   Copyright (C) ".strftime("%Y")." IEucd Inc. All rights reserved.")
        call append(line(".")+1, "*   ")
        call append(line(".")+2, "*   文件名称:".expand("%:t"))
        call append(line(".")+3, "*   创 建 者:SongTL, songtianlun@comleader.com.cn")
        call append(line(".")+4, "*   创建日期:".strftime("%Y年%m月%d日"))
        call append(line(".")+5, "*   描    述:")
        call append(line(".")+6, "*")
        call append(line(".")+7, "================================================================*/")
        call append(line(".")+8, "")
        call append(line(".")+9, "")
endfunc
" 加入shell,Makefile注释
func SetComment_sh()
        call setline(3, "#================================================================")
        call setline(4, "#   Copyright (C) ".strftime("%Y")." IEucd Inc. All rights reserved.")
        call setline(5, "#   ")
        call setline(6, "#   文件名称:".expand("%:t"))
        call setline(7, "#   创 建 者:SongTL, songtianlun@comleader.com.cn")
        call setline(8, "#   创建日期:".strftime("%Y年%m月%d日"))
        call setline(9, "#   描    述:")
        call setline(10, "#")
        call setline(11, "#================================================================")
        call setline(12, "")
        call setline(13, "")
endfunc
" 定义函数SetTitle,自动插入文件头 
func SetTitle()
        if &filetype == 'make'
                call setline(1,"")
                call setline(2,"")
                call SetComment_sh()

        elseif &filetype == 'sh'
                call setline(1,"#!/system/bin/sh")
                call setline(2,"")
                call SetComment_sh()

        else
             call SetComment()
             if expand("%:e") == 'hpp'
                  call append(line(".")+10, "#ifndef _".toupper(expand("%:t:r"))."_H")
                  call append(line(".")+11, "#define _".toupper(expand("%:t:r"))."_H")
                  call append(line(".")+12, "#ifdef __cplusplus")
                  call append(line(".")+13, "extern \"C\"")
                  call append(line(".")+14, "{")
                  call append(line(".")+15, "#endif")
                  call append(line(".")+16, "")
                  call append(line(".")+17, "#ifdef __cplusplus")
                  call append(line(".")+18, "}")
                  call append(line(".")+19, "#endif")
                  call append(line(".")+20, "#endif //".toupper(expand("%:t:r"))."_H")

             elseif expand("%:e") == 'h'
                call append(line(".")+10, "#pragma once")
             elseif &filetype == 'c'
                call append(line(".")+10,"#include \"".expand("%:t:r").".h\"")
             elseif &filetype == 'cpp'
                call append(line(".")+10, "#include \"".expand("%:t:r").".h\"")
             endif
        endif
endfun

使用效果:

https://imagehost-cdn.frytea.com/20200720192515.png

参考文献

VIM个性化配置(一)

配置

只需在Home目录创建一个 ~/.vimrc 文件即可以配置 vim 了,如需安装插件,在 ~/.vim 目录下创建一个bundle文件夹,插件装在里面。(需安装 Vundle 插件管理器),将以下内容拷入~/.vimrc 文件中即可。

vim ~/.vimrc
set nocompatible
filetype on

set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

" 这里根据自己需要的插件来设置,以下是我的配置 "
"
" YouCompleteMe:语句补全插件
set runtimepath+=~/.vim/bundle/YouCompleteMe
autocmd InsertLeave * if pumvisible() == 0|pclose|endif "离开插入模式后自动关闭预览窗口"
let g:ycm_collect_identifiers_from_tags_files = 1           " 开启 YCM基于标签引擎
let g:ycm_collect_identifiers_from_comments_and_strings = 1 " 注释与字符串中的内容也用于补全
let g:syntastic_ignore_files=[".*\.py$"]
let g:ycm_seed_identifiers_with_syntax = 1                  " 语法关键字补全
let g:ycm_complete_in_comments = 1
let g:ycm_confirm_extra_conf = 0                            " 关闭加载.ycm_extra_conf.py提示
let g:ycm_key_list_select_completion = ['<c-n>', '<Down>']  " 映射按键,没有这个会拦截掉tab, 导致其他插件的tab不能用.
let g:ycm_key_list_previous_completion = ['<c-p>', '<Up>']
let g:ycm_complete_in_comments = 1                          " 在注释输入中也能补全
let g:ycm_complete_in_strings = 1                           " 在字符串输入中也能补全
let g:ycm_collect_identifiers_from_comments_and_strings = 1 " 注释和字符串中的文字也会被收入补全
let g:ycm_global_ycm_extra_conf='~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py'
let g:ycm_show_diagnostics_ui = 0                           " 禁用语法检查
inoremap 
<expr> <CR> pumvisible() ? "\<C-y>" : "\<CR>"             " 回车即选中当前项
nnoremap <c-j> :YcmCompleter GoToDefinitionElseDeclaration<CR>     " 跳转到定义处
let g:ycm_min_num_of_chars_for_completion=2                 " 从第2个键入字符就开始罗列匹配项
"

" github 仓库中的插件 "
Plugin 'VundleVim/Vundle.vim'

Plugin 'vim-airline/vim-airline'
"vim-airline配置:优化vim界面"
"let g:airline#extensions#tabline#enabled = 1
" airline设置
" 显示颜色
set t_Co=256
set laststatus=2
" 使用powerline打过补丁的字体
let g:airline_powerline_fonts = 1
" 开启tabline
let g:airline#extensions#tabline#enabled = 1
" tabline中当前buffer两端的分隔字符
let g:airline#extensions#tabline#left_sep = ' '
" tabline中未激活buffer两端的分隔字符
let g:airline#extensions#tabline#left_alt_sep = ' '
" tabline中buffer显示编号
let g:airline#extensions#tabline#buffer_nr_show = 1
" 映射切换buffer的键位
nnoremap [b :bp
<CR>
nnoremap ]b :bn
<CR>
" 映射
<leader>num到num buffer
map 
<leader>1 :b 1<CR>
map 
<leader>2 :b 2<CR>
map 
<leader>3 :b 3<CR>
map 
<leader>4 :b 4<CR>
map 
<leader>5 :b 5<CR>
map 
<leader>6 :b 6<CR>
map 
<leader>7 :b 7<CR>
map 
<leader>8 :b 8<CR>
map 
<leader>9 :b 9<CR>

" vim-scripts 中的插件 "
Plugin 'taglist.vim'
"ctags 配置:F3快捷键显示程序中的各种tags,包括变量和函数等。
map 
<F3> :TlistToggle<CR>
let Tlist_Use_Right_Window=1
let Tlist_Show_One_File=1
let Tlist_Exit_OnlyWindow=1
let Tlist_WinWidt=25

Plugin 'The-NERD-tree'
"NERDTree 配置:F2快捷键显示当前目录树
map 
<F2> :NERDTreeToggle<CR>
let NERDTreeWinSize=25 

Plugin 'indentLine.vim'
Plugin 'delimitMate.vim'

" 非 github 仓库的插件"
" Plugin 'git://git.wincent.com/command-t.git'
" 本地仓库的插件 "

call vundle#end()

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"""""新文件标题
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"新建.c,.h,.sh,.java文件,自动插入文件头 
autocmd BufNewFile *.cpp,*.[ch],*.sh,*.java exec ":call SetTitle()" 
""定义函数SetTitle,自动插入文件头 
func SetTitle() 
    "如果文件类型为.sh文件 
    if &filetype == 'sh' 
        call setline(1, "##########################################################################") 
        call append(line("."), "# File Name: ".expand("%")) 
        call append(line(".")+1, "# Author: TL Song") 
        call append(line(".")+2, "# mail: songtianlun@frytea.com") 
        call append(line(".")+3, "# Created Time: ".strftime("%c")) 
        call append(line(".")+4, "#########################################################################") 
        call append(line(".")+5, "#!/bin/zsh")
        call append(line(".")+6, "PATH=/home/edison/bin:/home/edison/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/work/tools/gcc-3.4.5-glibc-2.3.6/bin")
        call append(line(".")+7, "export PATH")
        call append(line(".")+8, "")
    else 
        call setline(1, "/*************************************************************************") 
        call append(line("."), "    > File Name: ".expand("%")) 
        call append(line(".")+1, "  > Author: TL Song") 
        call append(line(".")+2, "  > Mail: songtianlun@frytea.com") 
        call append(line(".")+3, "  > Created Time: ".strftime("%c")) 
        call append(line(".")+4, " ************************************************************************/") 
        call append(line(".")+5, "")
    endif
    if &filetype == 'cpp'
        call append(line(".")+6, "#include
<iostream>")
        call append(line(".")+7, "using namespace std;")
        call append(line(".")+8, "")
    endif
    if &filetype == 'c'
        call append(line(".")+6, "#include<stdio.h>")
        call append(line(".")+7, "")
    endif
    "   if &filetype == 'java'
    "       call append(line(".")+6,"public class ".expand("%"))
    "       call append(line(".")+7,"")
    "   endif
    "新建文件后,自动定位到文件末尾
    autocmd BufNewFile * normal G
endfunc 
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"键盘命令
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

nmap 
<leader>w :w!<cr>
nmap 
<leader>f :find<cr>

" 映射全选+复制 ctrl+a
map <C-A> ggVGY
map! <C-A> <Esc>ggVGY
map 
<F12> gg=G
" 选中状态下 Ctrl+c 复制
vmap <C-c> "+y

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
""实用设置
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 设置当文件被改动时自动载入
set autoread
" quickfix模式
autocmd FileType c,cpp map 
<buffer> <leader><space> :w<cr>:make<cr>
"代码补全 
set completeopt=preview,menu 
"允许插件  
filetype plugin on
"共享剪贴板  
set clipboard=unnamed 
"从不备份  
set nobackup
"make 运行
:set makeprg=g++\ -Wall\ \ %
"自动保存
set autowrite
set ruler                   " 打开状态栏标尺
set cursorline              " 突出显示当前行
set magic                   " 设置魔术
set guioptions-=T           " 隐藏工具栏
set guioptions-=m           " 隐藏菜单栏
"set statusline=\ %<%F[%1*%M%*%n%R%H]%=\ %y\ %0(%{&fileformat}\ %{&encoding}\ %c:%l/%L%)\
" 设置在状态行显示的信息
set foldcolumn=0
" set foldmethod=indent 
set foldlevel=3 
set foldenable              " 开始折叠
"使用语法高亮定义代码折叠
set foldmethod=syntax
"打开文件是默认不折叠代码
set foldlevelstart=99
" 不要使用vi的键盘模式,而是vim自己的
set nocompatible
" 语法高亮
set syntax=on
" 去掉输入错误的提示声音
set noeb
" 在处理未保存或只读文件的时候,弹出确认
set confirm
" 自动缩进
set autoindent
set cindent
" Tab键的宽度
set tabstop=4
" 统一缩进为4
set softtabstop=4
set shiftwidth=4
" 不要用空格代替制表符
set noexpandtab
" 在行和段开始处使用制表符
set smarttab
" 显示行号
set number
" 历史记录数
set history=1000
"禁止生成临时文件
set nobackup
set noswapfile
"搜索忽略大小写
set ignorecase
"搜索逐字符高亮
set hlsearch
set incsearch
"行内替换
set gdefault
"编码设置
set enc=utf-8
set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936
"语言设置
set langmenu=zh_CN.UTF-8
set helplang=cn
" 我的状态行显示的内容(包括文件类型和解码)
set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")}
set statusline=[%F]%y%r%m%*%=[Line:%l/%L,Column:%c][%p%%]
" 总是显示状态行
set laststatus=2
" 命令行(在状态行下)的高度,默认为1,这里是2
set cmdheight=2
" 侦测文件类型
filetype on
" 载入文件类型插件
filetype plugin on
" 为特定文件类型载入相关缩进文件
filetype indent on
" 保存全局变量
set viminfo+=!
" 带有如下符号的单词不要被换行分割
set iskeyword+=_,$,@,%,#,-
" 字符间插入的像素行数目
set linespace=0
" 增强模式中的命令行自动完成操作
set wildmenu
" 使回格键(backspace)正常处理indent, eol, start等
set backspace=2
" 允许backspace和光标键跨越行边界
set whichwrap+=<,>,h,l
" 可以在buffer的任何地方使用鼠标(类似office中在工作区双击鼠标定位)
set mouse=a
set selection=exclusive
set selectmode=mouse,key
" 通过使用: commands命令,告诉我们文件的哪一行被改变过
set report=0
" 在被分割的窗口间显示空白,便于阅读
set fillchars=vert:\ ,stl:\ ,stlnc:\
" 高亮显示匹配的括号
set showmatch
" 匹配括号高亮的时间(单位是十分之一秒)
set matchtime=1
" 光标移动到buffer的顶部和底部时保持3行距离
set scrolloff=3
" 为C程序提供自动缩进
set smartindent
" 高亮显示普通txt文件(需要txt.vim脚本)
 au BufRead,BufNewFile *  setfiletype txt
"自动补全
:inoremap ( ()
<ESC>i
:inoremap ) <c-r>=ClosePair(')')<CR>
":inoremap { {
<CR>}<ESC>O
":inoremap } <c-r>=ClosePair('}')<CR>
:inoremap [ []
<ESC>i
:inoremap ] <c-r>=ClosePair(']')<CR>
:inoremap " ""
<ESC>i
:inoremap ' ''
<ESC>i
function! ClosePair(char)
    if getline('.')[col('.') - 1] == a:char
        return "\
<Right>"
    else
        return a:char
    endif
endfunction
filetype plugin indent on 
"打开文件类型检测, 加了这句才可以用智能补全
set completeopt=longest,menu
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

效果预览:

https://imagehost-cdn.frytea.com/20200726191412.png

后续步骤

Vim 版本升级(Vim8)

安装步骤

第一步,下载源码

Vim官方Github仓库下载目前最新的Vim Release版本

wget https://codeload.github.com/vim/vim/tar.gz/v8.2.1258

第二步,解压

$ mv v8.2.1258  vim-v8.2.1258.tar.gz
$ tar -xvzf vim-v8.2.1258.tar.gz

第三步,编译安装

$ cd vim-8.2.1258/
$ ./configure --prefix=$HOME/.local --enable-python3interp=yes && make && make install
  • 这里注意一下我们需要用configure配置一下安装的路径,将Vim8安装到自己账户的目录下,避免干扰到系统上的其他用户
  • --enable-python3interp=yes 添加 python3 支持

在这里可能会遇到 no terminal library found 错误:

no terminal library found
checking for tgetent()… configure: error: NOT FOUND!
      You need to install a terminal library; for example ncurses.
      Or specify the name of the library with –with-tlib.

解决方法:

# Ubuntu下解决方法:
$ sudo apt install libncurses5-dev

# CentOS 下
$ yum install ncurses-devel.x86_64

# 完成后重新进行这一步,建议删除

第四步,链接

利用alias将vim指令定向到刚刚安装的vim8,同时修改.bashrc确保之后一直能生效

alias vim='~/.local/bin/vim'
echo "alias vim='~/.local/bin/vim'" >> ~/.bashrc

第五步,检查

vim --version

参考文献

Windows 开机自启VMware虚拟机

由于进行Linux下软件开发,需要频繁使用 VMware 虚拟机,为提高效率找到一种开机启动启动 VMware 虚拟机的方法,可以大大提升效率。

第一步,编写脚本

首先编写 自启 脚本 vm_start.bat ,内容如下:

"C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe" start "E:\Virtual Machines\CentOS 7 64 位\CentOS 7 64 位.vmx" nogui

其中前面部分替换为自己 VMware 安装目录下的 vmrun.exe 文件所在路径,后部分替换为自己虚拟机的 *.vmx 文件路径。不要丢掉了双引号。

如果像我一样路径里面包含中文,记得将编码转化为 ANSI 编码即可正常使用,否则运行会乱码。

https://imagehost-cdn.frytea.com/20200722085533.png

如果需要关机自动关闭脚本 vm_stop.bat ,内容如下:

"C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe" stop "E:\Virtual Machines\CentOS 7 64 位\CentOS 7 64 位.vmx" soft

第二步,加入启动策略

这里有两种方法:

  • 将脚本加入开机启动策略
  • 将脚本拷入 启动 文件夹

首先第一种,运行 gpedit.msc > 用户配置 > windows设置 > 脚本(登录/注销) > 添加

第二种比较简单,将脚本拷入启动文件夹:

`X:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp(注:X为Win10系统盘盘符)`

比如,我的启动文件夹就是 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp

第三步,enjoy it!

参考文献

VIM 创建程序文件自动添加头部注释

修改 /etc/vimrc ,在文件最后添加以下内容:

" 当新建 .h .c .hpp .cpp .mk .sh等文件时自动调用SetTitle 函数
autocmd BufNewFile *.[ch],*.hpp,*.cpp,Makefile,*.mk,*.sh exec ":call SetTitle()"
" 加入注释 
func SetComment()
        call setline(1,"/*================================================================")
        call append(line("."),   "*   Copyright (C) ".strftime("%Y")." IEucd Inc. All rights reserved.")
        call append(line(".")+1, "*   ")
        call append(line(".")+2, "*   文件名称:".expand("%:t"))
        call append(line(".")+3, "*   创 建 者:SongTL, songtianlun@comleader.com.cn")
        call append(line(".")+4, "*   创建日期:".strftime("%Y年%m月%d日"))
        call append(line(".")+5, "*   描    述:")
        call append(line(".")+6, "*")
        call append(line(".")+7, "================================================================*/")
        call append(line(".")+8, "")
        call append(line(".")+9, "")
endfunc
" 加入shell,Makefile注释
func SetComment_sh()
        call setline(3, "#================================================================")
        call setline(4, "#   Copyright (C) ".strftime("%Y")." IEucd Inc. All rights reserved.")
        call setline(5, "#   ")
        call setline(6, "#   文件名称:".expand("%:t"))
        call setline(7, "#   创 建 者:SongTL, songtianlun@comleader.com.cn")
        call setline(8, "#   创建日期:".strftime("%Y年%m月%d日"))
        call setline(9, "#   描    述:")
        call setline(10, "#")
        call setline(11, "#================================================================")
        call setline(12, "")
        call setline(13, "")
endfunc
" 定义函数SetTitle,自动插入文件头 
func SetTitle()
        if &filetype == 'make'
                call setline(1,"")
                call setline(2,"")
                call SetComment_sh()

        elseif &filetype == 'sh'
                call setline(1,"#!/system/bin/sh")
                call setline(2,"")
                call SetComment_sh()

        else
             call SetComment()
             if expand("%:e") == 'hpp'
                  call append(line(".")+10, "#ifndef _".toupper(expand("%:t:r"))."_H")
                  call append(line(".")+11, "#define _".toupper(expand("%:t:r"))."_H")
                  call append(line(".")+12, "#ifdef __cplusplus")
                  call append(line(".")+13, "extern \"C\"")
                  call append(line(".")+14, "{")
                  call append(line(".")+15, "#endif")
                  call append(line(".")+16, "")
                  call append(line(".")+17, "#ifdef __cplusplus")
                  call append(line(".")+18, "}")
                  call append(line(".")+19, "#endif")
                  call append(line(".")+20, "#endif //".toupper(expand("%:t:r"))."_H")

             elseif expand("%:e") == 'h'
                call append(line(".")+10, "#pragma once")
             elseif &filetype == 'c'
                call append(line(".")+10,"#include \"".expand("%:t:r").".h\"")
             elseif &filetype == 'cpp'
                call append(line(".")+10, "#include \"".expand("%:t:r").".h\"")
             endif
        endif
endfun

使用效果:

https://imagehost-cdn.frytea.com/20200720192515.png

参考文献

【简记】Linux 计划任务 Crontab

cron 简介

cron 是 UNIX, SOLARIS,LINUX 下的一个十分有用的工具。通过 cron 脚本能使计划任务定期地在系统后台自动运行。

cron 命令

crontab -e  – 编辑该用户的 crontab,当指定 crontab 不存在时新建。 crontab -l – 列出该用户的 crontab。 crontab -r – 删除该用户的 crontab。 crontab -u<用户名称> – 指定要设定 crontab 的用户名称。

重启命令:

/etc/init.d/crond restart // 以路径方式重启
service crond restart // 以服务的方式重启

Linux Crontab 格式

Crontab 字段与允许的值 (Linux Crontab)

cron 实例

1、特定时间执行

cron 的基本用法是在特定的时间执行一项任务,如下是 6 月 10 上午 8:30 执行 Full backup shell script。 要注意的是时间字段采用的是 24 小时制,如果是下午 8 点,则改写为 20 点

30 08 10 06 * /home/ramesh/full-backup

30 – 第 30 分钟 08 – 早上 8 点 10 – 10 号 06 – 第 6 个月 (6 月) * – 一周的任何一天

2、 安排多个实例(比如一天执行两次)

下面的增量备份脚本每天执行两次。

每天于 11:00, 16:00 执行,逗号两侧的时间都会执行。

00 11,16 * * * /home/ramesh/bin/incremental-backup 00 – 第 0 分钟 (每小时开时) 11,16 – 早上 11 点与下午 4 点  – 每天  – 每个月 * – 一周的任何一天

3、让任务只在特定时间执行(比如仅当工作日时执行)

下面这个例子是每天 9:00-16:00 检查数据库状态(包括周六)

00 09-18 * * * /home/ramesh/bin/check-db-status 00 – 第 0 分钟 (每小时开时) 09-18 – 9 点, 10 点, 11 点, 12 点, 下午 1 点, 下午 2 点, 下午 3 点, 下午 4 点, 下午 5 点, 下午 6 点  – 每天  – 每个月 * – 一周的任何一天 如果只想工作日执行此操作

00 09-18 * * 1-5 /home/ramesh/bin/check-db-status 00 – 第 0 分钟 (每小时开时) 09-18 – 9 点, 10 点, 11 点, 12 点, 下午 1 点, 下午 2 点, 下午 3 点, 下午 4 点, 下午 5 点, 下午 6 点  – 每天  – 每个月 1-5 – 周一, 周二, 周三, 周四和周五 (工作日)

4、 安排每分钟都执行定时任务

理论情况下,没有每分钟都要执行的 shell,但下面这个例子,让我们更好的了解 crontab

* * * * * 命令
  • * 代表着所有可能取到的值,除了直接用 * 外,下面的几个例子也较为常用
  • 当指定 */5 在分钟字段,代表每五分钟。
  • 当指定 0-10/2 在分钟字段,代表在前十分钟的每两分钟

上面的例子对于其它四个字段同样试用

5、安排后台每十分钟执行定时任务

*/10 * * * * /home/ramesh/check-disk-space

有一些特殊的例子,可以用关键字替代上述五个字段 – reboot, midnight, yearly, hourly

Table: Cron special keywords and its meaning

6、每一年的第一分钟执行定时任务(@yearly)

下面的例子将在每一年的 1 月 1 日 0:00 执行

@yearly /home/ramesh/red-hat/bin/annual-maintenance

7、每月执行定时任务(@mothly)

下面的例子将在每月 1 日 0:00 执行

@monthly /home/ramesh/suse/bin/tape-backup

8、每天执行定时任务(@daily)

下面的例子将在每天 0:00 执行

@daily /home/ramesh/arch-linux/bin/cleanup-logs "day started"

9、每次重启时执行定时任务(@reboot)

@reboot CMD

10、如何用 mail 关键字禁止/重定向 cron 的邮件

默认情况下,crontab 将向布置定时任务的管理员发送邮件,如果想重定向此用户,添加并更新 MAIL

ramesh@dev-db$ crontab -l
MAIL="ramesh"

@yearly /home/ramesh/annual-maintenance
*/10 * * * * /home/ramesh/check-disk-space

如果不想任何人接收,则直接将 MAIL 置空

11、如何系秒每执行一个定时任务

无法安排每秒执行,因为最小处理单元是分钟,另一方面,没有什么理由让我们每秒都执行一任务

12、cron 中的 PATH 变量

上面的例子都是用绝对的路径

如果你想用相对的路径,设置环境变量可以在 crontab 增加

ramesh@dev-db$ crontab -l

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/home/ramesh

@yearly annual-maintenance
*/10 * * * * check-disk-space

13、从 cron 文件中定义 cron 任务

除了直接编辑外,你也可以先在一个文件中编辑好任务,再导入

ramesh@dev-db$ crontab -l
no crontab for ramesh

$ cat cron-file.txt
@yearly /home/ramesh/annual-maintenance
*/10 * * * * /home/ramesh/check-disk-space

ramesh@dev-db$ crontab cron-file.txt

ramesh@dev-db$ crontab -l
@yearly /home/ramesh/annual-maintenance

*/10 * * * * /home/ramesh/check-disk-space

应用时要注意,此操作会删除原有的cron任务

14、查看所有用户 cron 任务

$ cat /etc/passwd | cut -f 1 -d : |xargs -I {} crontab -l -u {}
30 08 10 06 * sar 1 10 > /root/sysstat/data.txt
30 6 */10 * * ls
no crontab for bin
no crontab for daemon
no crontab for adm
no crontab for lp
no crontab for sync
no crontab for shutdown
no crontab for halt
no crontab for mail
no crontab for operator
no crontab for games
no crontab for ftp
no crontab for nobody
no crontab for systemd-network
no crontab for dbus
no crontab for polkitd
no crontab for sshd
no crontab for postfix
no crontab for chrony
no crontab for ntp
no crontab for tcpdump
no crontab for nscd

参考文献

VS Code 免密登录Linux服务器

使用 VS Code 中提供的 Remote Development 可以实现连接远程服务器,管理文件、远程调试、远程管理等功能,实现远程开发。今天主要介绍如何通过配置SSH公钥实现 VC Code 免密登录 Linux 服务器。

前提条件

  • 安装 VS Code
  • 安装了 Remote Development 插件

部署步骤

第一步,服务器端部署公钥

参考:Linux部署私钥实现免密登录

第二步,找到 VS Code 配置文件

https://imagehost-cdn.frytea.com/20200720093404.png

第三步,修改 VS Code 配置文件

Host Ali-Dev-Test
  HostName *.*.*.*
  User root
  IdentityFile "H:\我的云端硬盘\Security\ssh-key\aliyun-frytea-edu-t5.pem"

按照上面的格式,指定主机名称、地址、用户以及密钥路径。

第四步,Enjoy it!

参考文献