Mac修正Vim无法git提交的问题

Git 可以使用Vim作为 Commit Message编辑器,上次不小心出现了以下错误:

1
error: There was a problem with the editor 'vim'.Please supply the message using either -m or -F option.

如果在 Vim 中编辑文本时因为按键失误出现类似这样:E492: Not an editor command… 的错误信息时,必然无法提交。

后来在 Google Group: vim_mac 这个帖子中找到了解决的办法,就是使用完整的 Vim 路径—— /usr/bin/vim :

1
git config --global core.editor /usr/bin/vim

看了一些别的博客,说有可能的原因是:
Vim 在遇到 Exx Error 时返回 Non-Zero code 是为了兼容 Posix,不过这种情况应该只会出现在使用 Ex Mode 时,Normal/Insert Mode 是不会这样的。

如何优雅的使用Vim

我的电脑

1
2
3
4
5
6
➜  ~  sw_vers
ProductName: Mac OS X
ProductVersion: 10.10.5
BuildVersion: 14F1021
➜ ~ python -V
Python 2.7.10

配置前的准备

默认大家是安装了 HomeBrew, 没有的话请自行安装

若是需要安装Python的代码提示 YouCompleteMe, 要求:

  • YouCompleteMe unavailable: requires Vim 7.3.598+
  • 还需要Python支持Python module

执行以下命令可以查看相关支持信息(+支持、-不支持)

1
2
3
4
➜  ~  vim --version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Apr 28 2016 11:12:36)
+cryptv +linebreak -python +vreplace
+cscope +lispindent +python3 +wildignore

若是版本不对 或者 not support python module,请执行

1
2
3
sudo mv /usr/bin/vim /usr/bin/vim_bk  # 把系统默认的vim备份了
brew install vim --with-python3 # 安装新的vim
# 若是下面的步骤执行不下去了,尝试一下 brew install vim --with-python
  • 最后还需安装 brew instal CMake

安装vim 插件

执行以下脚本

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
#!/bin/sh

if [ ! -d ~/.vim ]; then
mkdir ~/.vim
fi

cd ~/.vim

if [ ! -d bundle ]; then
mkdir bundle
fi

cd bundle
git clone https://github.com/VundleVim/Vundle.vim.git # 管理工具
git clone https://github.com/Lokaltog/vim-powerline.git #
git clone https://github.com/scrooloose/nerdtree.git # 目录树
git clone https://github.com/jistr/vim-nerdtree-tabs.git #
git clone https://github.com/vim-scripts/taglist.vim.git # 方法类跳转
git clone https://github.com/vim-scripts/AutoTag.git
git clone https://github.com/scrooloose/syntastic.git # js语法检测
git clone https://github.com/tpope/vim-fugitive.git # 显示Git信息
git clone https://github.com/Valloric/YouCompleteMe.git # python 自动补全
git clone https://github.com/hynek/vim-python-pep8-indent # pep8 python语法 需要在项目虚拟环境下 pip install pep8
git clone https://github.com/nvie/vim-flake8 # 代码风格检测 需要在项目虚拟环境下 pip install flake8
git clone https://github.com/Yggdroot/indentLine # 代码格式对齐线
git clone https://github.com:scrooloose/nerdcommenter.git # 快捷注释
# git clone https://github.com/vim-ruby/vim-ruby # ruby插件
cd YouCompleteMe
git submodule update --init --recursive
./install.py --clang-completer

cd ..
mkdir -p ~/.vim/autoload ~/.vim/bundle && curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim
cd ~
brew install ctags

以上所有vim插件都在GitHub上
若是要更新哪个插件,直接到插件目录下去git pull 就行了;
值得注意的是 最好查看下插件的README,看它的用发是否发生了改变,需要自行更新 .vimrc中的配置

.vimrc 配置文件

1
2
cd ~
vim .vimrc # 编辑 .vimrc 文件 内容如下
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
syntax on
set encoding=utf-8
" 自动缩进
set autoindent
set cindent
set autoread " 设置当文件被改动时自动载入
set wildmenu " 增强模式中的命令行自动完成操作
set showcmd " 输入的命令显示出来,看的清楚些
set whichwrap+=<,>,h,l " 允许backspace和光标键跨越行边界
set ruler " 显示标尺
set tabstop=4
set shiftwidth=4
set softtabstop=4
"为不同的文件类型设置不同的空格数替换TAB
autocmd FileType php,python,c,java,perl,shell,bash,vim,ruby,cpp set ai
autocmd FileType php,python,c,java,perl,shell,bash,vim,ruby,cpp set sw=4
autocmd FileType php,python,c,java,perl,shell,bash,vim,ruby,cpp set ts=4
autocmd FileType php,python,c,java,perl,shell,bash,vim,ruby,cpp set sts=4
autocmd FileType javascript,html,css,xml set ai
autocmd FileType javascript,html,css,xml set sw=2
autocmd FileType javascript,html,css,xml set ts=2
autocmd FileType javascript,html,css,xml set sts=2
set expandtab
set nu
set hlsearch
set incsearch
set colorcolumn=120
set cul "高亮光标所在行
autocmd InsertEnter * se cul " 用浅色高亮当前行
set scrolloff=3 " 光标移动到buffer的顶部和底部时保持3行距离
"set statusline=%<\ %n:%F\ %m%r%y%=%-35.(line:\ %l\ of\ %L,\ col:\ %c%V\ (%P)%)
set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")} "状态行显示的内容
set laststatus=2
set ignorecase
set backspace=indent,eol,start " backspace over everything in insert mode
set nocompatible " be iMproved, required
filetype off " required

set foldnestmax=10 "deepest fold is 10 levels
set foldlevel=1 "this is just what i use
set foldmethod=marker

set paste

map <F2> :mksession! ~/.vim_session <cr> " Quick write session with F2
map <F3> :source ~/.vim_session <cr> " And load session with F3

execute pathogen#infect()

function! ResCur()
if line("'\"") <= line("$")
normal! g`"
return 1
endif
endfunction

augroup resCur
autocmd!
autocmd BufWinEnter * call ResCur()
augroup END

filetype plugin indent on " required
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"""""新文件标题
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"新建.c,.h,.sh,.java文件,自动插入文件头
autocmd BufNewFile *.cpp,*.[ch],*.sh,*.rb,*.java,*.py exec ":call SetTitle()"
""定义函数SetTitle,自动插入文件头
func SetTitle()
"如果文件类型为.sh文件
if &filetype == 'sh'
call setline(1,"\#!/bin/bash")
call append(line("."), "")
elseif &filetype == 'python'
call setline(1,"#!/usr/bin/env python")
call append(line("."),"# coding=utf-8")
call append(line(".")+1, "")
endif
endfunc
autocmd BufNewFile * normal G

au BufNewFile,BufRead *.yml set filetype=xml
autocmd FileType python setlocal completeopt-=preview

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"""" 插件管理
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'
" All of your Plugins must be added before the following line
call vundle#end() " required

""""""""""""""""""""""""""""""""""""""""""""""""""""""
"Yggdroot/indentLine
let g:indentLine_char = '┊'
""""""""""""""""""""""""""""""""""""""""""""""""""""""
"powerline{
set guifont=PowerlineSymbols\ for\ Powerline
set nocompatible
set t_Co=256
let g:Powerline_stl_path_style = "full"
"}
""""""""""""""""""""""""""""""""""""""""""""""""""""""
"打开文件类型检测, 加了这句才可以用智能补全
set completeopt=preview,menu
set completeopt=longest,menu
"python补全
let g:pydiction_location = '~/.vim/after/complete-dict'
let g:pydiction_menu_height = 20
let g:miniBufExplMapWindowNavVim = 1
let g:miniBufExplMapWindowNavArrows = 1
let g:miniBufExplMapCTabSwitchBufs = 1
let g:miniBufExplModSelTarget = 1
" ycm 此处要设置成python版本2.7,不要设置成python3了
let g:ycm_path_to_python_interpreter="python"
""""""""""""""""""""""""""""""""""""""""""""""""""""""
"syntax check
set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*
let g:syntastic_always_populate_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0
let g:syntastic_auto_loc_list = 1
let g:syntastic_python_checkers=['flake8']
let g:syntastic_python_flake8_args='--ignore W391,E501 --max-line-length 119'
let g:syntastic_loc_list_height=3
let g:syntastic_enable_highlighting=0
""""""""""""""""""""""""""""""""""""""""""""""""""""""
"ctags
set tags=./tags,tags;
" Tag list (ctags)
let Tlist_Ctags_Cmd = '/usr/local/bin/ctags'
let Tlist_Show_One_File = 1 "不同时显示多个文件的tag,只显示当前文件的
let Tlist_File_Fold_Auto_Close = 1
let Tlist_Exit_OnlyWindow = 1 "如果taglist窗口是最后一个窗口,则退出vim
let Tlist_Use_Right_Window = 1 "在右侧窗口中显示taglist窗口
nmap tl :Tlist<cr>
""""""""""""""""""""""""""""""""""""""""""""""""""""""
"so that when you preview the new file takes up 80% and the file explorer the other 20%.
let g:netrw_winsize=25
let g:netrw_altv = 2
let g:netrw_browse_split = 3
let g:netrw_keepdir = 0
let NERDTreeWinSize=30
"let g:nerdtree_tabs_open_on_console_startup=1
"列出当前目录文件
map <F3> :NERDTreeToggle<CR>
imap <F3> <ESC> :NERDTreeToggle<CR>
"当打开vim且没有文件时自动打开NERDTree
autocmd vimenter * if !argc() | NERDTree | endif
" 只剩 NERDTree时自动关闭
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTreeType") && b:NERDTreeType == "primary") | q | endif
" 忽略的文件不加载
set wildignore+=**/fe-dist/**
set wildignore+=**/node_modules/**
set wildignore+=**/log/**
set wildignore+=**/static/**
set wildignore+=*.swp,*.zip,*.pyc,.git/
set path=.,,**
""""""""""""""""""""""""""""""""""""""""""""""""""""""
"Yggdroot/indentLine
let g:indentLine_char = '┊'
""""""""""""""""""""""""""""""""""""""""""""""""""""""

" 注释的时候自动加个空格, 强迫症必配
" let g:NERDSpaceDelims=1
let mapleader=","

用 vundle 管理 vim 插件

其实上面脚本一键执行也挺方便的,此处只是稍微介绍一下 vundle 的用法。

可在 .vimrc 文件中添加配置

1
2
3
4
5
6
7
8
Bundle 'cespare/vim-golang'
Bundle 'taglist.vim'
Bundle 'dhruvasagar/vim-table-mode'
Bundle 'godlygeek/tabular'
Bundle 'derekwyatt/vim-scala'
Bundle 'kien/ctrlp.vim'
Bundle 'Valloric/YouCompleteMe'
Bundle 'Yggdroot/indentLine'

随便开个窗口,从控制台打开vim,然后执行-> :BundleInstall ,vundle会自动下载声明的插件并安装到 ./vim/bundle 目录里面

到此,安装结束,可以畅游vim了。

ubuntu 解决语言设置错误的问题

在使用 ubuntu 命令行登录的时候,出现:

1
2
3
4
5
6
7
8
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LC_MESSAGES = "zh_CN.UTF-8",
LANG = "zh_CN.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

这样的错误,虽说不影响使用,但是感觉挺烦的说。

那么要如何解决呢,有必要记录下:

安装 localepurge 管理语言文件

1
sudo apt-get install localepurge

选择我们想要的语言,例如 en_US.UTF-8zh_CN.UTF-8

当然也可以使用以下命令再次进行配置:

1
sudo dpkg-reconfigure localepurge

生成自己想要的语言

1
sudo locale-gen zh_CN.UTF-8 en_US.UTF-8

打印出当前的配置信息

1
locale

到此,搞定!!!

默认情况下终端 ssh 的时候会将本地的 locale 传到服务器中,可以通过命令指定 ssh 服务器的语言:

1
LC_ALL=en_US.UTF-8 ssh <host>

hexo/Jekyll + github搭建自己的博客

首先,必须有一个GitHub账号,相信大家都有,没有的话自己去创建吧。

一、GitHub Pages的使用

1. 创建一个分支,使用你的GitHub name

Head over to GitHub and create a new repository named username.github.io, where username is your username (or organization name) on GitHub.

我的GitHub name是 SkylerHu,以我的名字为例。

2. 初始化项目

若是借助Jekyll和hexo的话,只需clone下来即可。

已下步骤是基于terminal的git命令,若是使用界面工具,自己去GitHub Pages

1
2
3
4
5
6
~$ git clone https://github.com/SkylerHu/SkylerHu.github.io
~$ cd SkylerHu.github.io
~$ echo "Hello World" > index.html
~$ git add --all
~$ git commit -m "Initial commit"
~$ git push -u origin master

也可以在index.html中添加HTML内容,然后在push

一切OK之后,可以访问 http://SkylerHu.github.io. 可以查看index.html的内容。这个网址就是你的博客网址。

二、使用Jekyll

上面新建的项目中,Settings中可以看到GitHubPages相关配置,官方推荐使用Jekyll
GitHub Pages Settings

1. 初始化

安装需要Ruby环境,没有的话自行安装。

1
2
~$ gem install jekyll
~$ jekyll new my-awesome-site

把项目生成的所有文件,全部copy到SkylerHu.github.io目录下.

2. 目录结构

3. 本地启动预览

1
2
~$ cd SkylerHu.github.io
~/SkylerHu.github.io$ jekyll serve

直接访问http://localhost:4000/ 就可以看到你的网站了。

4. 写文章

在目录/SkylerHu.github.io/_posts/下新建xxxx.md;
格式需要按照模板提供的去写;

5. 部署

1
2
~/SkylerHu.github.io$ git add --all
~/SkylerHu.github.io$ git push

6. 使用自己的域名

1) 添加CNAME文件push到GitHub
1
~/SkylerHu.github.io$ echo "pages.skylerhu.com" > CNAME
2) 域名解析

使pages.skylerhu.com解析到 SkylerHu.github.io
注意选择 解析类型是CNAME

7. 主题

推荐网站:

可以根据自己的喜好去选择主题,都大同小异。

三、使用hexo

之所有使用hexo,因为好多网友都说这个比较好,所有研究了一下使用方法。

需要安装Node.js

1. 安装

1
~$ sudo npm install -g hexo

2. 初始化

1
2
3
4
5
6
7
~$ cd blog
# 初始化
~/blog$ hexo init
# 生成静态页面,把markdown转化成html,hexo g 也行
~/blog$ hexo generate
# 启动本地服务,hexo s 也行
~/blog$ hexo server

其他hexo命令

若是之后nodejs升级了,需要执行一下 npm --registry=https://registry.npm.taobao.org install
或者直接执行 npm install, 有参数的意思是使用淘宝源

3. 配置GitHub

编辑blog目录下_config.yml文件,详见hexo配置

1
~/blog$ vim _config.yml

找到deploy配置如下:

1
2
3
4
5
deploy:
type: git
repo:https://github.com/SkylerHu/SkylerHu.github.io.git
branch:master
message: commit的message,默认 Site updated: {{ now('YYYY-MM-DD HH:mm:ss') }}

保存后执行命令安装插件hexo-deployer-git

1
~/blog$ npm install hexo-deployer-git --save

4. 配置RSS

编辑_config.yml配置feed

1
2
3
4
5
feed:
type: atom
path: atom.xml
limit: 20
hub:

安装插件hexo-generator-feed

1
~/blog$ npm install hexo-generator-feed --save

5. 部署GitHub Pages

部署之前可以修改_confi.yml中deploy.message作为git commit的message

1
2
3
4
5
# 每次修改之后都需要clean和generate
~/blog$ hexo clean
~/blog$ hexo generate
# hexo d 也可以
~/blog$ hexo deploy

会生成一个.deploy_git 文件夹同步到GitHub项目中。

5. 主题

推荐网站https://hexo.io/themes/
我自己使用的是 hexo-theme-yilia

1
~$ git clone https://github.com/litten/hexo-theme-yilia.git themes/yilia

修改hexo根目录下的 _config.yml : theme: yilia

6. 使用自己的域名

同Jekyll一样,也需要修改域名解析,同样也要在GitHub项目下添加CNAME文件。

注意:

  • 不能直接在deploy_git目录下直接添加CNAME文件,每次generate之后会删除
  • 需要添加到source文件夹下echo "pages.skylerhu.com" > source/CNAME

7. 其他配置

可以在blog/_config.yml配置语言和时区

1
2
language: zh-Hans
timezone: Asia/Shanghai

我的网站还添加了多说评论百度统计,具体使用详见推荐网站

四、比较

Jekyll hexo
语言 Ruby node.js
效率 So fast 稍慢
部署 需要多个命令 直接使用git命令

两个之间都可以互相迁移,看个人操作习惯和爱好吧。

遇到的问题

升级了Node.js后,发现在项目目录中执行hexo相关命令会报出错误

1
2
3
[Error: Module version mismatch. Expected 47, got 46.]
{ [Error: Cannot find module './build/default/DTraceProviderBindings'] code: 'MODULE_NOT_FOUND' }
{ [Error: Cannot find module './build/Debug/DTraceProviderBindings'] code: 'MODULE_NOT_FOUND' }

解决方案如下:

  • 执行npm uninstall hexo卸载hexo;
  • 重新安装hexo,npm install -g hexo;
  • 到博客目录执行npm install,hexo clean,hexo generate

Shadowsocks+SwitchySharp

若要申请VPS可使用这个DigtalOcean,会赠送你$10用于购买VPS。

ShadowSocks官网

1. gcc安装

1
2
3
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-4.8

2. go 环境搭建

1
2
wget https://storage.googleapis.com/golang/go1.4.linux-386.tar.gz
sudo tar -C /usr/src -xzf go1.4.linux-386.tar.gz

在 $HOME/.bashrc 文件末添加如下

1
2
3
export GOROOT=/usr/src/go
export PATH=$PATH:$GOROOT/bin
export GOPATH=$HOME/go

执行

1
2
3
4
source ~/.bashrc

cd $GOROOT/src
sudo ./all.bash (若是缺少,apt-get install gccgo-go)

3. 安装git

1
sudo apt-get install git-core

4. 安装

1
2
go get github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-server
shadowsocks-go

5. 配置

1
2
3
4
cd /etc/
sudo mkdir shadowsocks
cd shadowsocks
sudo touch config.json

6. 写入

1
2
3
4
5
6
7
8
9
10
11
12
{
"server": "0.0.0.0",
"local_address": "127.0.0.1",
"local_port": 1080,
"timeout": 300,
"method": "aes-256-cfb",
"fast_open": false,
"port_password": {
"12345": "xxx1",
"12346": "xxx2"
}
}

7. 启动关闭

1
2
3
4
5
6
7
8
9
10
cd ~
vim .profile
添加
export PATH="$PATH:/root/go/bin"

source .profile
shadowsocks-server -c /etc/shadowsocks/config.json -d start
shadowsocks-server -c /etc/shadowsocks/config.json -d stop

nohup shadowsocks-server -c /etc/shadowsocks/config.json

8. 开机启动

编辑 /etc/rc.local,在exit 0之前

/root/go/bin/shadowsocks-server -c /etc/shadowsocks/config.json start

9. 配置SwitchySharp

1
(fbcdn|akamaihd|pixnet)\.net|wretch\.cc|t\.co|goo\.gl|(google(usercontent|apis)*|chrome|staticflickr|imdb|ytimg|gstatic|html5rocks|amazonaws|github|tumblr|addthis|wordpress|blogger|(blog|app)spot|friendfeed|twitter|facebook|youtube|dropbox|feedburner|googleapis|android)\.com

http://autoproxy-gfwlist.googlecode.com/svn/trunk/gfwlist.txt (这个连接404访问不了, 可用下面链接)
https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt

Ubuntu搭建VPN

若要申请VPS可使用这个DigtalOcean,会赠送你$10用于购买VPS。

采用PPTP搭建VPN,优点是配置简单快捷。将亲身过程记录下来供亲们参考,并将过程中遇到的问题也一一列举出来解决方式。。。

直接上步骤:

1.第一步需要安装PPTP,以用来提供VPN服务.

1
sudo apt-get install pptpd

如果有问题的话比如提示找不到之类的,apt-get update 一下应该就可以了,然后再来一次就会自动完成安装。

2.装好了之后我们需要进行配置一下以让它可以使用.

1
sudo vi /etc/pptpd.conf

取消掉以下 2 行的注释:

1
2
localip 192.168.0.1
remoteip 192.168.0.234-238,192.168.0.245

分别是通过VPN连接后主机和客户端所使用的IP,可以自行修改。注意这个IP在下面还会用的到。

3.然后我们需要分配账号给自己使用.

1
sudo vi /etc/ppp/chap-secrets

这个是用户列表文件

在里面添加账户按如下格式

1
username  pptpd  "password"  *

username为你的用户名password为你的密码,密码用引号引起,最后的*号表示允许在任意IP连接到服务

4.至此服务弄好了

如果你sudo service pptpd restart一下,就应该已经能连接到该VPN了,但是连接了之后会发现还访问不了外网。然后我们需要让他能访问外网。首先,

1
sudo vi /etc/ppp/pptpd-options

找到ms-dns,取消掉注释,改成你喜欢的DNS比如8.8.8.8, 8.8.4.4

5.然后我们要开启内核IP转发

1
sudo vi /etc/sysctl.conf

取消掉 net.ipv4.ip_forward=1 这一行的注释.

1
sysctl -p

6.然后我们需要安装iptables,用来实现请求的NAT转发

1
sudo apt-get install iptables

然后开启NAT转发.

1
sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE

192.168.0.0/24是你在上面设置的IP段,让这个段转发

注意eth0是你连接外网的那块网卡,不一定是0也有可能是1或者看你的机器哪块网卡连的外网了。这样就以NAT的方式请求外网的东西了。不知道你的机器哪块网卡连的外网的话ifconfig一下看看哪个网卡是外网IP就知道了。

1
2
iptables -t nat -A POSTROUTING -s 192.168.217.0/24 -o eth0 -j MASQUERADE
iptables-save > /etc/iptables.pptp

只需执行上面的命令,下面的命令可以备用。

1
2
3
iptables -F	//清空所有规则
iptables -t nat -vnL POSTROUTING --line-number //查看nat表
iptables -t nat -D POSTROUTING [num] //删除nat表中postrouting的第一条规则

开启iptables转发

在/etc/network/if-up.d/目录下创建iptables文件,内容如下:

1
2
\#\!/bin/sh
iptables-restore < /etc/iptables.pptp

给脚本添加执行权限:

1
chmod +x /etc/network/if-up.d/iptables

####7.最后,我们需要重启服务,让配置生效

1
2
sudo service pptpd restart
/etc/init.d/pptpd restart

git仓库迁移

已有项目名为trainingHub

新的gitlab服务器地址github.com

新的gitlab服务中的User为Skyler

1. 第一步

在自己的gitlab后台建立一个新的项目,其地址为git@github.com:Skyler/trainingHub.git

2. 第二步

进入本地的trainingHub目录,然后执行下面两个命令:

1
2
git remote remove origin
git remote add origin git@github.com:Skyler/trainingHub.git

3. 最后直接pullpush

1
2
git remote remove origin
git remote add origin git@gitlab.pookor.com:Skyler/trainingHub.git
若是有多个分支需要迁移

git remote add branch_name git@gitlab.pookor.com:Skyler/trainingHub.git

push所有分支

git push --all origin

注意

可强制覆盖远程服务器

git push --all --force origin

Linux(SUSE)Redis服务的安装使用

1、下载源码,解压缩后编译源码。

1
2
3
tar -zxzf redis-2.8.3.tar.gz
cd redis-2.8.3
make && make install

2、编译完成后

有四个可执行文件redis-server、redis-benchmark、redis-cli和redis.conf。然后拷贝到一个目录下。

1
2
3
4
5
mkdir /usr/redis
cp src/redis-server /usr/redis
cp src/redis-benchmark /usr/redis
cp src/redis-cli /usr/redis
cp redis.conf /usr/redis

3、配置Redis

vim /usr/redis/redis.conf

可参考http://blog.csdn.net/java2000_wl/article/details/8520593

按如下方式修改相关参数:

1
2
3
4
端口默认:6379
daemonize yes
timeout 300
tcp-keepalive 60

4、启动Redis服务

1
2
cd /usr/redis
./redis-server redis.conf

5、然后用客户端测试一下是否启动成功

1
2
3
4
5
$ ./redis-cli
$ redis> settest” “testredis”
$ OK
$ redis> get “test
$ " testredis "

6.java客户端的使用

jar包下载地址:http://download.csdn.net/detail/kuailebeihun/8714073

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import java.util.HashMap;  
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import play.Play;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
* Redis工具类,用于获取RedisPool. 参考官网说明如下: You shouldn't use the same instance from different threads because you'll have strange errors. And sometimes creating lots of Jedis instances is not good enough because it means lots of sockets and connections, which leads to strange errors as well. A single Jedis instance is not threadsafe! To avoid these problems, you should use JedisPool, which is a threadsafe pool of network connections. This way you can overcome those strange errors and achieve great performance. To use it, init a pool: JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost"); You can store the pool somewhere statically, it is thread-safe. JedisPoolConfig includes a number of helpful Redis-specific connection pooling defaults. For example, Jedis with JedisPoolConfig will close a connection after 300 seconds if it has not been returned.
*
* @author bqwang
*/
public class JedisUtil {
/**
* 私有构造器.
*/
private JedisUtil() {

}

/**
* 获取连接池.
*
* @return 连接池实例
*/
private static JedisPool getPool(String ip, int port) {
JedisPool pool = null;
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(Integer.parseInt(Play.configuration.getProperty("redis.pool.maxIdle")));
config.setMaxTotal(Integer.parseInt(Play.configuration.getProperty("redis.pool.maxTotal")));
config.setTestOnBorrow(Play.configuration.getProperty("redis.pool.testOnBorrow") == "true" ? true : false);
config.setTestOnReturn(Play.configuration.getProperty("redis.pool.testOnReturn") == "true" ? true : false);
try {
/**
* 如果你遇到 java.net.SocketTimeoutException: Read timed out exception的异常信息 请尝试在构造JedisPool的时候设置自己的超时值. JedisPool默认的超时时间是2秒(单位毫秒)
*/
pool = new JedisPool(config, ip, port, Integer.parseInt(Play.configuration.getProperty("redis.pool.timeout")));
} catch (Exception e) {
System.out.println("get pool:" + e.getMessage() + "==>" + e.getCause().getMessage());
e.printStackTrace();
} finally {
System.out.println("get pool 获取连接池.....");
}
return pool;
}

/**
* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到时才会装载,从而实现了延迟加载。
*/
private static class RedisUtilHolder {
/**
* 静态初始化器,由JVM来保证线程安全
*/
private static JedisUtil instance = new JedisUtil();
}

/**
* 当getInstance方法第一次被调用的时候,它第一次读取 RedisUtilHolder.instance,导致RedisUtilHolder类得到初始化;而这个类在装载并被初始化的时候,会初始化它的静 态域,从而创建RedisUtil的实例,由于是静态的域,因此只会在虚拟机装载类的时候初始化一次,并由虚拟机来保证它的线程安全性。 这个模式的优势在于,getInstance方法并没有被同步,并且只是执行一个域的访问,因此延迟初始化并没有增加任何访问成本。
*/
public static JedisUtil getInstance() {
return RedisUtilHolder.instance;
}

/**
* 获取Redis实例.
*
* @return Redis工具类实例
*/
public Set<String> getJedisData(String key) {
Set<String> resultSet = null;
JedisPool pool = null;
Jedis jedis = null;
String ip = Play.configuration.getProperty("redis.server.ip");
int port = Integer.parseInt(Play.configuration.getProperty("redis.server.port"));
// int retryTimes = Integer.parseInt(Play.configuration.getProperty("redis.pool.retryTimes"));
// int count = 0;
// count++;
try {
pool = getPool(ip, port);
jedis = pool.getResource();
resultSet = jedis.smembers(key);
// 清空redis中的消息
jedis.del(key);
} catch (Exception e) {
System.out.println("get jedis:" + e.getMessage() + "==>" + e.getCause().getMessage());
e.printStackTrace();
} finally {
// 销毁对象
System.out.println("get Jedis ++++++ 销毁对象");
if (pool != null) {
pool.returnBrokenResource(jedis);
}
}
return resultSet;
}
}

Linux(SUSE) nginx反向代理配置,负载均衡

1. 安装jdk

sudo rpm -ivh jdk-7u71-linux-x64.rpm

设置环境变量:
vim /etc/profile

在底部加入:

$set java environment

1
2
3
4
JAVA_HOME=/usr/java/jdk1.7.0_71
CLASSPATH=.:$JAVA_HOME/lib/tools.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH
vim /etc/profile.d/java.sh

加入:

$set java environment

1
2
3
4
JAVA_HOME=/usr/java/jdk1.7.0_71
CLASSPATH=.:$JAVA_HOME/lib/tools.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH

2. 安装包准备

下载地址:http://download.csdn.net/detail/kuailebeihun/8318449

1
2
3
4
tar -zxvf 
tar -zxvf nginx-1.7.8.tar.gz
tar -zxvf openssl-1.0.0o.tar.gz
tar -zxvf zlib-1.2.8.tar.gz

先下载好zlib和openssl
编译nginx时,联合编译zlib和openssl

3. 编译安装zlib

1
2
3
4
cd zlib-1.2.8/
./configure
make
make install

4. 编译安装openssl

1
2
3
cd openssl-1.0.0o/
./config
make && make install

5. 编译安装pcre

1
2
3
cd pcre-8.12/
./configure
make && make install

6. 联合编译安装nginx

1
2
3
4
$ cd nginx-1.7.8
$ ./configure --user=nobody --group=nobody --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/data/moa/pcre-8.12 --with-openssl=/data/moa/openssl-1.0.0o
$ make
$ make install

vi objs/Makefile

查找configure --disable-shared,在1158行,删除./configure --disable-shared, 保存
    :st nu可显示行号
    :1089直接跳到1158行,:/configure可以搜索

make && make install

7. nginx配置

cd /usr/local/webserver/nginx/

配置

vim conf/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
gzip  on;
upstream wplay {
server 192.168.11.6:80;
}
location / {
proxy_pass http://wplay;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_max_temp_file_size 0;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}

8.启动、重启命令

1
2
3
cd ..
cd sbin/
./nginx

重启

nginx -s reload

9. 参考资料