mysql基本命令

安装mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# https://dev.mysql.com/downloads/repo/yum/ 查看对应版本
wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm
rpm -ivh mysql57-community-release-el7-9.noarch.rpm
yum install -y mysql-server
echo "skip-grant-tables" >> /etc/my.cnf
systemctl start mysqld
mysql -uroot -proot
flush privileges;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';
sed -i -e '/^skip-grant-tables/d' /etc/my.cnf
systemctl restart mysqld
mysql -uroot -proot
CREATE DATABASE `hive` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
grant all privileges on *.* to root@localhost identified by 'root';
flush privileges;

权限和修改配置文件问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# ubuntu的配置文件和docker mysql:5.7一样
vim /etc/mysql/my.cnf
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
# 可以在上面两个目录下,创建*.conf来为启动mysql增加参数
# 默认使用到的是/etc/mysql/mysql.conf.d/mysqld.cnf
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
skip-grant-tables
# bind-address = 127.0.0.1 #注释掉就可以远程访问了
bind-address = 0.0.0.0 # 或者这样
# 允许本地ip的blog用户,使用blog密码访问blog数据库
GRANT ALL PRIVILEGES ON blog.* TO 'blog'@'localhost' IDENTIFIED BY 'blog';
# 允许远程的任何ip的root用户 使用root密码 访问所有数据库
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
# 不用密码登录
grant all privileges on *.* to root@localhost identified by '' with grant option;
# 刷新权限
FLUSH PRIVILEGES;

字符集问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 查看字符集的设置
show variables like 'character_set%';
+--------------------------+----------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------+
| character_set_client | utf8 #客户端来源数据使用的字符集
| character_set_connection | utf8 # 连接层字符集
| character_set_database | utf8 #当前选中数据库的默认字符集
| character_set_filesystem | binary
| character_set_results | utf8 #查询结果字符集 |
| character_set_server | utf8 #默认的内部操作字符集 |
| character_set_system | utf8 #系统元数据(字段名等)字符集
| character_sets_dir | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
# 或者使用 status 命令
# 一般情况下,只需要设置如下两个选项,就会得到上面的结果
set character_set_server='utf8';
set character_set_database='utf8';
# 如果还是有中文乱码问题,则是在创建数据库时,没有设置默认字符集
CREATE DATABASE `hive` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
alter database hive default character set utf8;

导出导入

1
2
3
4
5
6
7
8
# 将数据库hive所有表导出(导入的时候就会导出所有的表)
mysqldump -uroot -proot hive >hive.sql
# 只导出 某些表(导入时只导入这些表)
mysqldump -hxx -uroot -proot --databases qhh --tables goods_goodscategory goods_banner goods_goods goods_goodsimage >db1.sql
# 导入
mysql -h0.0.0.0 -uroot -proot hive < hive.sql

连接mysql

1
2
3
4
5
# mysqladmin修改密码
mysqladmin -u root -p password 'root'
# mysqladmin创建/删除数据库
msyqladmin -uroot -p craete/drop hive

mysql基本命令

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
1. SELECT user(); -- 查看当前哪个用户登录到数据库
2. SHOW DATABASES; -- 查看DBMS中有哪些数据库
3. USE 数据库名 --更换要使用的数据库
4. SELECT database(); -- 查看当前正在使用哪个数据库
5. CREATE DATABASE 数据库名; -- 建立一个数据库
6. CREATE USER '用户名'@'%' IDENTIFIED BY '密码';
C:\Program Files\MySQL\MySQL Server 5.7\bin
mysql -u tom -p
FLUSH PRIVILEGES
7. GRANT ALL ON world.* to 'tom'@'%'; -- 授予tom用户在world数据库中所有的权限
8. REVOKE ALL ON world.* from 'tom'@'%'; -- 回收tom用户在world数据库中所有的权限
9. SELECT "Hello, World!" AS "String";
10. SELECT "Hello, World!" AS "String" FROM dual;
11. SELECT now(); -- 显示当前数据库系统中的日期
12. SELECT code, name, gnp FROM world.country; -- 选择world数据库中country表格中code, name, gnp三列的内容进行显示
13. SHOW TABLES; -- 当前数据库中存在哪些表格
14. \g可以替代分号作为结尾
15. \G 将表格中的数据纵向排列显示
16. DELIMITER $$ -- 改变结束符号
DELIMITER ;
17. status -- 查看一些基本信息
18. \c -- 放弃当前语句
19. SOURCE c:\789.txt -- 执行789.txt文件中的内容
\. c:\789.txt -- 同上句,意思完全相同
20. TEE /home/name/111.txt -- 打开记录日志功能
NOTEE; -- 关闭日志记录功能
insert into test(id, name) values(1, 'Tom');
update test set name='XX';
select * from test where name='Tom' and (age > 4 or hige like '%0' or sex in ('男','女')) order by id asc/desc; --%就相当于正则中的*
SELECT coalesce(name, '总数'), SUM(singin) as singin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
delete from test where id=1; --清空表中的内容
21.
CREATE TABLE new_table1(
id int NOT NULL AUTO_INCREMENT,
name varchar(20) default femn,
birthday date,
salary double,
sex boolean,
primary key (id) --constraint pk_id primary key (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 建立表innodb才支持事务
SHOW CREATE TABLE table_name \G;
22. DESC new_table1; -- 查看表结构
23. INSERT INTO new_table1(id, name, birthday, salary, sex) VALUES (1, 'Tom', DATE'1982-05-17', 5000.0, true); -- 插入一行数据
24. SELECT * FROM new_table1; -- 查看表中内容
25. TRUNCATE TABLE new_table1; -- 清除表中内容
26. DROP TABLE new_table1; -- 删除表
27. ALTER TABLE new_table1 modify id long; -- 修改列
28. ALTER TABLE new_table1 add xxx integer; -- 添加列
29. ALTER TABLE new_table1 drop xxx; -- 删除列
ALTER TABLE table_name CHANGE id id1 INT
ALTER TABLE testalter_tbl RENAME TO alter_tbl; --修改表名
主键约束=唯一性约束+非空约束
alter table test
add constraint pk_id primary key(id); 主键约束
alter table test
add constraint un_name unique(name); 唯一性约束:唯一但是允许非空
alter table test
add constraint ck_id check id >=1; 检查性约束
alter table emp
add constraint fk_deptno
foreign key(deptno) references dept(deptno);
外键就是另外一张表中的主键
alter table test
drop constraint `ck_id`;
select count(*) from test;
select max(id) from test;
select min(id) from test;
select avg(id) from test;
select sum(id) from test;
子查询 一个查询语句里面还套有一个查询语句.
select deptno from emp where ename='SCOTT';
select empno, ename, deptno from emp where deptno=20;
select empno, ename, deptno from emp
where deptno = (select deptno from emp where ename='SCOTT');
select empno, ename, deptno from emp as e1
where sal> (select avg(sal) from emp as e2 where e1.deptno=e2.deptno);--
-- 各部门有多少人高于本部门平均工资
select empno, ename, deptno from emp as e1
where sal<ANY(select sal from emp where deptno=30 ) AND deptno<>30;--
Share Comments

mongodb基本命令

先去mongodb官网下载mongod,配置好环境变量.最好也再下个robomongo,进行更好的图形界面管理

mongodb官方文档

mongodb中文文档

启动Mongod:

1
mongod --dbpath /home/python/data/mongodb --logpath /home/python/data/log --auth

或者用配置文件的方式启动:

1
2
3
4
5
6
mongod -f ./mongod.conf
vim ./mongod.conf
dbpath = /home/python/data/mongodb/
logpath = /home/python/data/log
port = 27017
auth = true

进入Mongo的CLI:

1
2
3
monogo -uusername -ppasswd 192.168.0.197:27017/db
# 如果有语言上的错误
export LC_ALL=C

选择admin数据库,并认证:

1
2
use admin
db.auth('username','password')

指定好当前数据库后,用db命令查看,之后用密码登陆.

查看所有的数据库

1
show dbs

创建或选定数据库

1
2
use 1 # 该命令将创建一个新的数据库,如果它不存在,否则将返回现有的数据库.
db.dropDatabase('1') # 删除数据库

创建集合(表),删除表,显示所有表

1
2
3
db.createCollection('test')
db.test.drop()
show collections

创建文档(记录)

1
db.test_table.insert({'1':1})

指定数据库,一定要先选定再创建,创建用户角色

1
2
3
4
5
6
use test
db.createUser( {
user: "femn2014",
pwd: "femn2014",
roles: [ { role : "readWrite", db: "test" } ]
});

role:”sysadmin”,”read”,”readWrite”,”sysadmin”和”root”角色只能在第一次创建一次,之后创建的必须是其它的角色,同时也要注意db:’xxx’要改变,如果指定的是admin数据库,则此用户可以看到所有的数据库,并只是针对db:’test’这个数据库有读写操作.

指定数据库之后,查看用户

1
2
use test
db.getUsers()

一旦创建好用户之后,就必须要切换到admin数据库中,才能进行对用户角色的管理

用admin数据库,查看,管理所有数据库中的所有用户

1
2
3
use admin
db.system.users.find()
db.system.users.remove({user:'femn2014'}) 删除用户

得到test表的索引

1
db.test.getIndexes()

创建新的索引,此命令不会覆盖掉之前的索引

1
db.test.ensureIndex({'mobile':1})

创建二维索引,通过查询location这个数组,来得到文档

1
2
db.test.ensureIndex({"location" : "2d"},{"background" : true},
{min:-180,max:180})

MongoDB的Geospatial Indexing 2d默认取值范围[-179,-179]到[180,180] 包含这两个点,超出范围将报错

备份Mongo:

1
2
3
mongodump --host=192.168.1.217 --port=27017 --username=username \
--password=passwd --authenticationDatabase admin -dMongodb \
-cfemn -o /home/python/nosql_dump

恢复Mongo:

1
2
3
4
5
6
mongorestore -udba -pdba --host=60.205.140.13 --port=27017 \
--authenticationDatabase admin -dbozhongboyue -cvideo \
--drop /home/python/nosql_dump/1-5/bozhongboyue/video.bson
# 不经常使用如下命令
mongoexport --host=192.168.1.217 --port=27017 --username=username \
--password=passwd --authenticationDatabase admin -dMongodb -cfemn -o femn.json
Share Comments

ghost下载与使用

在VPS中,推荐下载最新的ghost

1
2
3
4
5
6
7
8
9
10
11
yum install gcc nodejs
npm install -g ghost-cli
mkdir /var/www/blog
cd /var/www/blog
ghost install local
http://localhost:2368/
# 将url换成你博客的地址
vim config.development.json
url: http://www.femnyy.com
ghost restart
http://www.femnyy.com

配置一下nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
vim /etc/nginx/conf.d/ghost.conf
server { # 定义一个虚拟主机
listen 80;
#server_name myip;
#server_name 0.0.0.0; 上面的公网IP也不行了,
#server_name mydomians; error
server_name myip www.femnyy.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
}
}
nginx -t
systemctl start nginx
systemctl enable nginx
setsebool -P httpd_can_network_connect true

访问 http://www.femnyy.com or http://myip/ghost

ghost 命令

1
2
3
ghost -h
# 其它命令
ghost ls/update/start/stop/restart

ghost管理界面的一些基本操作

同时在管理界面能操作的,就不要去动服务器中的ghost代码,本人能力有限,改了几次,配置都不能用了,只能重新安装(在旧版本中)

  1. 设置标签 再将Tab 设置成Navigation,同样新版本也可以操作Design了.

  2. 备份你的博客 导入博客
    Labs –> Export /Import

  3. 提高被搜索的概率
    setting –> Meta Date –> 输入搜索时的关键字

开始写博客

  1. 有关Markdown的语法手册

  2. 图片的处理
    使用七牛的对象存储 或者用sm.ms支持https

不推荐安装旧版本,旧版本安装不好友,想更新ghost版本也费劲,主要是有可以还安不成功

参考于此
install nodejs and setting npm source

1
2
3
4
5
6
7
8
9
10
11
12
yum -y update
yum install -y gcc-c++ make unzip netstat
curl --silent --location https://rpm.nodesource.com/setup_4.x | bash -
yum -y install nodejs
node -v
mkdir -p /var/www/
cd /var/www/
wget https://ghost.org/zip/ghost-latest.zip
unzip -uo ghost-latest.zip -d /var/www/ghost
cd ghost
npm config set registry http://registry.npmjs.org/
npm config set strict-ssl false

其中当npm install –production,下载依赖包时,可能会遇到内存不足的问题,可以通过增加交换空间来解决

1
2
3
4
5
6
7
8
sudo dd if=/dev/zero of=/swapfile bs=1024 count=1024k
sudo mkswap /swapfile
sudo swapon /swapfile
vim /etc/fstab
echo 10 | sudo tee /proc/sys/vm/swappiness
echo vm.swappiness = 10 | sudo tee -a /etc/sysctl.conf
sudo chown root:root /swapfile
sudo chmod 0600 /swapfile

install ghost

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cd /var/www/ghost
npm install --production
# start ghost
cp config.example.js config.js
vim config.js
config = {
production: {
url: 'http://myip'
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=2368/tcp
firewall-cmd --reload
npm start --production
ss -lnp |grep 2368
http://localhost:2368/ghost
kill -9 **

use pm2 manage ghost 之后就可以不用 nohup npm start –production 启动了

1
2
3
4
5
6
7
8
npm install -g pm2
echo "export NODE_ENV=production" &gt;&gt; ~/.profile
. ~/.profile
pm2 start index.js --name ghost
# pm2其它命令
pm2 show/start/stop ghost
pm2 status/logs/save
# 自从我修改了default.hbs之后,pm2就用不了了,害得我还得去重新install ghost

install nginx

1
2
3
4
yum -y install epel-release
yum -y update
yum -y install nginx
# 配置方法和最新的ghost配置一样

访问 http://www.femnyy.com or http://myip/ghost

如果是在国内安装的话,可能会比较慢,推荐用淘宝镜像安装,你可以使用我们定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:

1
npm install -g cnpm --registry=https://registry.npm.taobao.org

update nodejs npm

1
2
3
sudo npm cache clean -f
sudo npm install -g n
sudo n stable

ghost文档帮助

Share Comments

vim基本语法

普通模式下

操作符
>G >gg # 缩进 y复制 d删除
C == c$  #c是修改,删除之后进入插入模式
s == cl # l一个字符 aw一个单词(iw不涉及到空格,ciw推荐) ap一个段落
S == ^cc # 删除一整行
# g命令空间
g~l # 反转大小写
guw # 转化成小写
gUU # 转化成大写
:!nginx -s reload # 使用外部命令

当前文件中的移动

u # 撤消
<ctrl-r> # 重做
动作命令
w b e ge # 对单词 动作的移动程度和方向
W B E gE # 对字串 动作的移动程度和方向
* 和 #符号  # 匹配光标当前的所有单词
% # 匹配括号移动 
f+ # 查找当前行的下一个'+'字符,定位到'+' F上一个
t+ # 查找当前行的下一个'+'字符,定位到'+'的上一个字符 T上一个
3fa → 在当前行查找第三个出现的a 

; # 重复
, # 退回
yaw yt,  f,dt. d/ge<CR> # 查找动作告诉d操作符删除什么
#Vim的文本对象由两个字符组成,第一个字符永远是i或a.文本对象自身并不是动作命令,不能用它们在文档中移动
# 但我们却可以在可视化及操作符待决模式中使用文本对象
#操作分隔符的文本对象 m{a-zA-Z}要在其内部
a)==ab  a}==aB  at#一对XML标签 it #XML标签内部
vi) ci)
# 操作文本块的文本对象
daw ciw

# 设置位置标记
m{a-zA-Z}#小写每个缓冲区局部可见,大写全局可见
mm `m
# Vim的自动位置标记
'' # 当前文件中上次跳转动作之前的位置
'. # 上次修改过的地方
'^ #     插入
'[ # 上次修改或复制的起始位置
'] #             结束
'< #     高亮选区
'> #                 结束
# 括号间的跳转
%

# 当不同文件之间的移动和跳转
任何改变当前窗口中活动文件的命令,都可以称为跳转命令
Vim会把执行跳转命令之前和之后的光标位置,记录到跳转列表中



'<ff>'    
@: # 重复上次的Ex命令
:s%/old/new/g # 替换
1<ctrl-a> # 对当前行的一下数字加1  1<ctrl-x>:减一

# 重绘屏幕
zz #把当前行显示在窗口正中
<ctrl-d>(D) # 向下滚屏
<ctrl-u>(U) #   上
H/M/L # 跳到屏幕最上,中,下方

# 可视化模式
v

# 命令行模式
:

# 命令行窗口
q:

# 替换模式
R gR
r{char} gr{char} # 覆盖一个字符之后,马上又回到普通模式

#特别一点
ga #查看任意字符的编码 分别以10,16,8进制的形式显示其字符编码
J将下面的一整行,都提到光标行的末尾
<ctrl-g> # 显示当前文件文件名及状态

寄存器

# Vim操作的是寄存器,而并非剪贴板
# "{register}前缀的方式指定要用的寄存器,若不指明则使用无名寄存器
"ayiw "bdd ""yiw "+yy:delete c # 分别 对应寄存器a,b,",c中 
"ap   "bp  ""p   :put c       # 对应的复制
# x,s,d,c,y,p命令都会覆盖无名寄存器

# 无名寄存器("") ""p==p
yaw daw "0p
# 有名寄存器("a-"z)
# 黑洞寄存器("_)
# 复制专用寄存器("0) y命令不仅会被拷贝到无名寄存器中,还拷贝到复制专用寄存器中

# ubuntu 和mint默认安装的vim是不支持系统剪切、粘贴版的
sudo apt-get install -y vim-gnome
# 对于非GUI版本的vim,剪切板是不可用的,解决方案很简单,安装一下就是了:
sudo apt-get install gvim

# 系统剪贴板("+)
# 将系统剪贴板的内容粘贴到Vim内部
"+p  # 插入模式下<ctrl-r>+,",a,0
# 将Vim的文本捕获到系统剪贴板
"+yy
"%p # "%当前文件名
".p  # ".上次插入的文本

# 只读(read-only)寄存器:
":,分别缓存最近命令
".,最近插入文本
"%,当前文件名
"#,当前交替文件名

# 代换单词
yiw jww ve p
yiw jww  ciw<ctrl-r>0<Esc>

宏:在录制一个宏时,要确保每条命令都可被重复执行,同时禁止使用鼠标

而且当动作命令(j,n)停止时,宏将中止运行

#打任意数目的按键操作录制到寄存器,用于之后的回放
# 把命令序列录制成宏
qa #录制宏的开始 q{register},从而指定一个用于保存宏的寄存器
A;<Esc>
Ivar <Esc>
q # 停止宏录制
j @a j@@
:reg a  # 查看寄存器的内容
@a # @{register} 执行指定寄存器的内容,
@@ # 重复最近高过的宏

10@a # 加次数回放宏 .命令不能执行次数
f+  s_+_<Esc>  qq;.q 22@q

# 串行的运行宏 j :next

    10@a # 加次数回放宏 .命令不能执行次数
# 并行的运行宏

    :'<,'>normal @a # 单个文件的多行并行运行宏

    :args *.py # 建立目标文件列表
    :edit!
    :argdo normal @a
    # 当在多个文件中 进行并行运行宏时,执行宏一旦失败,不方便找到到底哪个失败了
    :wall

# 给宏追加命令 
qA # Vim会录制按键操作,但会把它们附加到寄存器a原有的内容之后
# 编辑宏
:put a # 将宏复制到缓冲区,当前光标的下方,而 "ap 复制到当前光标之后
# 在缓冲区进行对宏的编辑
0 "ay$ dd # 将宏从缓冲区复制回寄存器

插入模式

<ctrl-h>
<ctrl-w>
<ctrl-u> # 都是删除操作

# 插入-普通模式
<ctrl-o> #切换到插入-普通模式,在此后可执行一条普通模式下的命令后,再回到插入模式
<ctrl-o>zz #

# 复制专用寄存器("0) y命令不仅会被拷贝到无名寄存器中,还拷贝到复制专用寄存器中
<ctrl-r>0 # 0就是寄存器的名字 在命令行中yaw,默认寄存器的名字是0
<ctrl-r><ctrl-p>0 # 它会按原义插入寄存器内的文本,并修正任何不必要的缩进
<ctrl-r>=9*9<CR> # 表达式寄存器  <ctrl-r>=
<C-p>或是<C-n>,自动补齐功

<ctrl-v>065 # A用字符编码插入字符,vim所接受的字符编码共包含3位数
<ctrl-v>u00bf # 编码超过3位的,可以用4位16进制编码来输入
<ctrl-v><Tab> # 如果后面跟一个非数字键,它会插入这个键本身所代表的字符

可视模式

v V <ctrl-v>
o # 切换高亮选区的活动端
gv # 重选上次的高亮选区
yyp-->Vr# # ####横编排
<ctrl-v>3j$ #竖编排 
= # 自动给缩进 

命令行(EX命令)

@: # 在普通模式下执行 重复上次的Ex命令
/
<ctrl-r>= # 访问表达式寄存器也会激活命令行模式

# 有些命令可以在插入和命令行模式下通用
<ctrl-r>0 #复制寄存器的内容
<ctrl-h>
<ctrl-w>
<ctrl-u> # 都是删除操作 

/the/
?the?

:1,$ == :% # 整个文件
:. # 光标所有行
:0 #虚拟行 位于文件第一行上方

# 删除行
:3d == 3G+dd
:.d # 删除当前行

# 复制行t,移动行m
:6t. # :[range]t{address} 把第六行复制到当前行下方
:t6                        当前        第六行
:t. == yyp
:'<,'>t$ # 将高亮选区的内容复制到文本结尾处

A;
:'<,'>normal . == :'<,'>normal A; # 对高亮选区中的每一行,对其执行普通模式下的 . 命令. 

# 自动补全Ex命令
<ctrl-d> <Tab> <Shfit-Tab>
:colors<Tab>
:colorscheme <Tab>

# 把当前光标的单词插入到命令行
<ctrl-r><ctrl-w>
# 把当前光标的字串插入到命令行
<ctrl-r><ctrl-a>


#  命令行窗口,就像一个常规的Vim缓冲区,只不过它的内容都对应着命令历史中的一个条目
q: # 打开Ex 命令历史 k j键进行移动 ,<CR>将会把当前行的内容当成Ex命令执行  
q/ # 打开查找
:q #关闭命令行窗口 像操作普通Vim窗口一样 其它的操作也可以
<ctrl-f> # 从命令行模式切换到命令行窗口

# 运行shell
:!{cmd} # 执行一次性命令
:shell  # 启动一个交互的shell会话  exit  # 退出此shell并返回Vim
# 也可以在普通模式下 <ctrl-z>挂起Vim进程,$jobs  $fg [作业号]
:read !{cmd} # 将标准输出插入到光标下方
:[range]write !{cmd} # 将range(默认是整个文件)每行内容,作为此命令的输入
:%!sort -t ',' -k 2 # 以逗号分隔,按第二个字段进行排序


:tabnew # 创建新标签页
:split 文件路径 #分割窗口,如果不指定文件路径,默认是分割本文件
:set ignorecase #查找单词时需要忽略大小写
:set hlsearch # 可以将查找的内容设置成高亮
:set history=200 #设置保存命令的条数

参数列表(vi的一个功能)是缓冲区列表(Vim增加的功能)的强力补充

vim vim_grammar.md linux.md    
:ls #缓冲区列表 %哪个缓冲区在当前容器中可见 #代表轮换文件<ctrl-^>进行快速切换
# Vim是用缓冲区列表对打开的文件进行管理的

# 选择缓冲区
:buffer N/bufname # N是Vim自动分配的编号由上面的命令行得知  bufname是文件名
:bprev
:bnext 
:bfirst
:blast  
#退出(保存)所有的缓冲区
:qall!
:wall

# 删除缓冲区
:bdelete N1 N2

# 用参数列表将缓冲区分组
# 查看参数列表
:args
:args *.py # 建立目标文件列表

#如果活动缓冲区的内容发生了变化,Vim会在离开缓冲区时自动将其设为隐藏(默认会有错误信息'文件已修改但未保存')
#'hidden'设置让我们用一条;argdo {cmd}或 bufdo{cmd}命令就可以修改一组缓冲区.

分割窗口

# 创建分割窗口
<ctrl-w>s    
<ctrl-w>v    
:sp[lit] {file} #载入新文件
:vsp[lit] {file}
# 关闭窗口
<ctrl-w>c    #关闭活动窗口  :clo[se]
<ctrl-w>o    #保存活动容器,关闭其它所有窗口 :on[ly]
# 切换窗口
<ctrl-w>w    # 窗口循环切换
<ctrl-w>h j k l    
#改变窗口
<ctrl-w>=    
[N]<ctrl-w>_ # 最大化高度

[N]<ctrl-w>| #       宽度
[N]<ctrl-w>< # >

在Vim中,标签页是可以容纳一系列窗口的容器口

:tabnew # 创建新标签页
:tabe[dit] {filename} # 在新标签页打开{filename} 如果没有指定文件,会建立一个新标签页,里面包含一个空缓冲区
:<ctrl-w>T  #当标签页中包含了不只一个窗口时,用此命令 把当前窗口移到一个新标签页
:tabc[lose]  # 关闭当前所有标签页的窗口
:tabo[nly]  # 关闭其它
[N]gt #       下  :tabn[ext] 
[N]gT # 切换到上一标签页  :tabp[revious]

打开文件

#Vim也有工作目录的概念,这各bash及其他shell是一样的
#相对于活动文件目录下打开一个文件
:edit %:h<Tab>  # %代表活动缓冲区的完整文件路径 :h修饰符会去除文件名 也就是此命令会被展开为当前文件所有目录的路径
:set path+=app/** # 匹配app/目录下所有子目录
:find 文件名

# netrw管理文件系统
# 打开文件管理器
$ vim .
:edit %:h ==:e . ==:Explore ==:E
# 上面的操作都会代替当前的缓冲区内容
# 当要保存到不存在的目录中时
:!mkdir -p %:h #-p创建任何不存在的中间目录

# 我们可以把任务委派给一个以sudo运行的shell进程,来完成工作
:w !sudo tee % >/dev/null # :w将缓冲区的内容作为sudo tee的标准输入,%是当前文件
# 此时Vim会检测到该文件被一个外部程序改了,所以Vim会提示我们做出选择,是保留缓冲区的还是载入磁盘上的版本

vim对于ctage的支持,
1.我们可以快速地跳到到函数及类的定义之处,实现浏览整个代码库的目的.(基于标签的跳转)
2.用于建立自动补全的单词列表

安装和运行ctage

sudo apt-get install exuberant-ctags

sudo apt install linuxbrew-wrapper
# 检测系统是否安装了ctags以及路径正确与否
brew install ctags
ctags --help

用ctags创建代码库的索引

# 手动创建索引
cd ~/app1.6
ctags -R *
# 应该可以用!cd /home/python/app1.6 && ctags -R *
# Linux下的C/C++的程序员,使用VIM+Ctags的组合来写程序也许是最佳的选择
# 好像没有递归子目录,所以为子目录创建索引
cd main && ctags -R *
cd ../app1.6 #必须要cd到此目录或者 main目录下,可由 :set tags 查看
vim runner
# 这样本地的所有代码,都正确的创建了索引,但源代码还是没有办法创建索引

:tabnew /home/python/app1.6/runner.py
:set tags?
<ctrl-]> # 会从当前所在的关键字跳转到它的定义处 ,
g<ctrl-]>

<ctrl-t> # 充当着后退按钮 
Share Comments

编译工具

1
vim bar.c
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
#include <stdio.h>
int foo(int n);
void bar(int m);
int
main(void){
int a;
char *s = "hello, world";
printf("%s\n",&s[7]);
a = 5;
foo(a);
return 0;
}
int
foo(int n){
int b;
b = n;
b *=2;
bar(b);
return b;
}
void
bar(int m){
printf("hi,i am bar!\n");
}

gcc程序编译

1
gcc -g -Wall bar.c -o bar

编译可分为四个阶段:
1.预处理:宏定义,头文件
2.编译:c–>汇编语言
3.汇编:汇编成目标文件 .o (二进制文件)
4.链接:把所有的目标文件和库文件链接成一个可执行的文件

gcc 参数

-I /home/include:指定头文件路径,先找预设路径
-L /usr/lib:库文件路径,先找指定目录,再找系统预设路径
-lfun:库文件中指定函数库 libfun.a
-static:静态链接库文件 .a为后缀,将所需要的函数copy到执行文件中
而动态链接库以 .so为后缀 指明当程序执行时,首先必须载入这个库,缺省操作
-Wall:生成所有的警告信息
-g:产生调试工具所必须的
-c:只生成一个.o后缀的目标文件

gdb程序调试

1
gdb bar
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
break main //内存中main函数的入口地址 b 行号 ,b 文件名:行号
run //r
list //l
print a //殘值而已,不是我们赋的值 p
print s //也是殘值 print &a next next next step next print &b
print s+90 //通过gdb 可以在内存中任意跳转
next //n
print s
next
print s[7]
print &s[7]
print a //残值
next
print a
step //进入foo子函数 s
next
next
print n
print b
step //进入bar函数
print m
continue //返回0 正常退出 c继续运行程序
b 5 if i=10 当i等于10时第5行断点生效
delete 断点编号 :删除断点
quit //q

Makefile工程管理

当有很多个文件都需要编译时,不可能一个一个的去gcc吧
通过make命令就能够使整个软件工程完成编译和链接
make在执行行,需要一个命名为Makefile的文件,它描述了整个工程的编译,链接等规则

Share Comments

git基本使用

安装及配置git

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
sudo apt-get install git
# 配置git的用户信息
git config --global user.name="femn2014"
# git config --global user.name "femn2014" # 旧版本
git config --global user.emial="1643076443@qq.com"
# --system(/etc/gitconfig 针对所有用户) --global(~/.gitconfig 针对当前用户)
# --local(.git/config 针对当前项目 默认行为)
# 删除配置
git config --unset --global user.name="femn2014"
# 生成ssh密钥
ssh-keygen -t rsa -C "1643076443@qq.com"
# 将~/.ssh/id_rsa.pub内容上传到github服务器上,并检测是否可连接
bash ssh-add
ssh -T git@github.com
# git clone
git clone <remote_repo>
# 指定分支
git clone -b develop <remote_repo>

git 基本概念以及基本用法

git基本概念

git 目录结构

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
# 创建一个目录
mkdir demoGit && cd demoGit
git init # 初始化一个git仓库
tree -a # 查看目录结构
. # 项目文件,也就是所谓的工作区(Working Directory)
└── .git # 本地git仓库实体
├── branches
├── config # git项目级别的配置文件 git config --local 修改的就是这个文件
├── description # 项目描述信息
├── HEAD # 标记当前工作区所有的分支,是一个写有分支指针的文件
├── hooks # git默认的挂钩脚本
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── index # 索引文件,也就是所谓的暂存区,git add 命令会修改这个文件
├── info
│   └── exclude # 配置本地范围内忽略文件,不上传
├── logs # refs的历史记录,如HEAD,master分支和远程origin/master分支
│   │   ├── HEAD
│   │   └── refs
│   │   └── heads
│   │   └── master
├── objects # 是本地git仓库实际存放对象和文件快照的地方,也称作为仓库(Repository)
│   ├── info
│   └── pack
└── refs # 存放分支,标签文件和远程仓库
git branch/tag/push [branch_name]命令操作的就是这个目录下的文件
├── heads
└── tags

git 基本命令

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
# 创建两个文件
$ touch README.md hello
# 查看项目的当前状态 -s是简短的结果输出
$ git status -s
?? README.md
?? hello
# ??表示没有被索引状态
$ git add .
$ git status -s
A README.md
A hello
# A 表示已经创建索引
$ echo -e "master分支 生产版本号:1.0.0\n">>README.md
$ git status -s
AM README.md
A hello
# AM表示被索引,但在工作区已经被修改还没有add M[空格]表示缓存区被修改还没有commit
$ git rm -f hello
# 删除工作区以及暂存区的文件,如果有--cached参数则只删除暂存区
$ git mv REANDE README.md # 重命名文件
$ git commit -m 'xx' # 将暂存区的内容写入仓库
# commit 所有修改的內容送到目前的分支上
$ git commit --amend -m "master分支 生产版本号:1.0.0" # 产生一个新的提交替换之前的一次提交

diff工具,合并冲突工具:meld

1
2
3
4
5
6
7
sudo apt-get install meld
# 当安装好git,再安meld或kdiff3时,git会自动配置好
git difftool origin/master
# git difftool -t vimdiff # 使用vimdiff diff工具
# 当有冲突时
git mergetool

pull拉取 push提交 checkout分支

1
2
3
4
5
6
7
8
9
10
11
12
# git pull url/远程仓库名 远程分支名[默认同本地HEAD分支名]:[本地分支:默认是HEAD所在的分支]
# git pull = git fetch + git merge
# 在本地的master分支下拉取origin/next分支,并在master分支下进行合并
git pull origin next:master
# git push url/远程仓库名 本地分支名:[远程分支名,默认同本地分支名一样]
git push -u origin master
# 相当于是 git push -u origin master:master
git checkout -b develop [master]# 默认是在HEAD所有分支的前提下,
# 并创建一个名为develop的分支,并切换到此分支

主分支提交,并为开发者提供一个develop分支

1
2
3
4
5
6
7
8
9
git remote add origin git@gitlab.com:leipengkai/demoGit.git
git push -u origin master
git checkout -b develop # 创建一个新分支并切换到此分支,结合下面的那个命令
# git branch develop && git checkout develop
git branch # 查看分支 -d [branch_name]参数删除合并之后的无用分支 -D 强制删除分支
# develop分支也会有master的所有信息
git push -u origin develop

多个开发者,自己在开发功能的分支上开发

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
git clone git@gitlab.com:leipengkai/demoGit.git
git checkout -b develop origin/develop # 在远程origin的develop分支的基本下,创建一个分支
git checkout -b feature-femn develop # 用于开发的功能分支
echo -e "feature-femn分支 开发了一个好玩的功能\n">>README.md
git add .
git commit -m "feature-femn分支 开发了一个好玩的功能"
# 合并其它同事的功能
git checkout develop
git pull origin develop:develop # 确保本地的develop分支为最新的,develop:develop最好是这种形式
git merge feature-femn
# 将自己的功能上传
git push -u origin develop:develop # 没有冲突时直接使用
######################################################
git checkout feature-femn
echo -e "feature-femn分支 共同开发了第二个好玩的功能\n">>README.md
git add .
git commit -m "feature-femn分支 共同开发了第二个好玩的功能"
git checkout develop
# 在网页端模拟同事完成第二个功能的部分
# (fufu在网页端完成第二个功能的主要的部分)
git pull origin develop:develop
git merge feature-femn
git mergetool # 解决冲突
git add .
git commit -m "共同完成第二个功能"
git push -u origin develop:develop
# git branch -d feature-femn # 可删除本地分支

发布分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 当所有同事都开发,测试完成之后,进行发布
git checkout -b release-1.0.0 develop
# 合并master分支
git checkout master
git merge release-1.0.0
git push -u origin master
# 合并修改到 developer 分支
git checkout develop
git merge release-1.0.0
git push -u origin develop
# 可删除发布分支
git branch -d release-1.0.0
# 为master分支 发行版本的tag
git checkout master
git tag -a 1.0.0 -m "Initial public release" master
git push --tags
git log --oneline --graph --decorate --all -n 20

修复(master或develop分支的)bug

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
git checkout -b bugfix-#001(bug 分支名称) master(或develop)
# 去修bug,并commit
vim .gitignore
*.pyc 加上这句
git add .
git commit -m "忽略.pyc文件"
git checkout master
git merge bugfix-#001
git push
git branch -d bugfix-#001
# 在develop中开发
git checkout develop
vim .gitignore
.idea
git add .
git commit -m "忽略.idea目录"
git push origin develop:develop
# 合并master分支
git checkout -b merge2 master
git checkout develop
git merge merge2
git mergetool
git commit -m "忽略.pyc文件和.idea目录"
# 如果不push的话,再使用 commit --amend是不会有多分支的
git push origin develop:develop
# 突然又想改一点小地方,不想单独提交一次
vim .gitignore
Docker/nginx/log
git add .
git commit --amend -m "忽略.pyc文件,.idea目录 Docker/nginx/log目录"
git log --oneline --graph --decorate --all -n 20
* 275fcc8 (HEAD -> develop) 忽略.pyc文件,.idea目录 Docker/nginx/log目录
|\
| | * 91d6986 (origin/develop) 忽略.pyc文件和.idea目录
| | |\
| |/ /
|/| /
| |/
| * 6a78c8c (origin/master, merge2, master) 忽略.pyc文件
* | 586c422 忽略.idea目录
|/
* 8fac61d (tag: 1.0.0) 共同完成第二个功能
|\
| * 09759fd (feature-femn) feature-femn分支 共同开发了第二个好玩的功能
* | 7e18791 fufu在网页端完成第二个功能的主要的部分
|/
* 90e6505 feature-femn分支 开发了一个好玩的功能
* 10a5209 master分支 生产版本号:1.0
git pull
# git pull origin origin/develop:develop
git mergetool
git commit -m "忽略规则"
git push origin develop:develop

创建标签

1
2
3
4
5
6
7
8
9
10
11
git tag -a v1.0 -m "tag 1"
git log --oneline --decorate --graph
* 9229ec9 (HEAD -> new_branch, tag: v1.0) new_branch 1
* 6c0975b master 1
git tag
git show v1.0
# 默认情况下,git push 并不会把标签传送到远端服务器上
# git push origin v1.0 # 分享标签到远程仓库
# git push origin --tags # 推送所有本地新增的标签
# git tag -d tagname # 删除标签

图解GIT

.gitignore规则

  1. 不会对空目录进行索引和跟踪
  2. dir(dir/*):表示.gitignore所在目录下的dir目录的所有内容,不会被跟踪,同时也不会生成此目录.

    不可以写成./dir

    .gitignore文件生效问题

    1
    2
    3
    # 已经track且有改动的文件添加ignore规则
    git rm -r --cached *.pyc # 要忽略的文件
    # 最好是创建项目的时候,写要ignore规则

删除上次commit(HEAD)

1
2
3
4
5
6
7
git reset --soft HEAD~1(回滚到HEAD~1版本,就是删除HEAD)
# 如果没有 --soft,则在删除上次(HEAD)的同时,还会将Stage区的内容替换成HEAD~1
# 将本地更新强行推送至服务器(想要删除某个远程commit提出的)
# 强制push使得远程commit与本地的commit一模一样
git push --force origin master
# 注意:此参数不能在团队中使用,不然别人的提出就会被删除了
Share Comments

linux 服务与进程

linux启动流程

通电 –>BIOS(哪个磁盘有MBR) –>MBR(哪个分区为要开启的OS) –>OS –>/boot(kernel) –>init(PID:1) –>/etc/rc*.d/ –>/etc/init.d/ –>用户登陆(/etc/profilc–>~/.profile .bash_login .bash_profile–>~/.bashrc)

添加启动项

/etc/rc[0~6].d 这7个目录中,每个目录分别存放着对应运行级别加载时需要关闭或启动的服务,每个脚本文件都对应着/etc/init.d/目录下具体的服务

K开头的脚本文件代表运行级别加载时需要关闭的,S开头的代表需要执行,数字代表执行顺序
因此,当我们需要开机启动自己的脚本时,只需要将可执行脚本丢在/etc/init.d目录下,然后在/etc/rc*.d中建立软链接即可

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo shmod 755 /etc/init.d/ssh
cd /etc/init.d
sudo update-rc.d ssh defaults 95 5 . # 执行顺序95,加入运行级别5级中
#即在rc*.d中各建立了一个软连接,因此也可以自己手动建立软连接,如下
ln -s /etc/init.d/ssh /etc/rc5.d/S95sshd
sudo /etc/init.d/ssh start
sudo service S95sshd start
# 开机启动
sudo apt-get install openssh-server
# 二选一
sudo /etc/init.d/ssh start
sudo service sshd start

简单的启动命令

Linux 在启动的时候会执行 /etc/rc.local 里面的脚本,所以只要在这里添加执行命令就可以

1
2
3
4
5
6
7
8
9
10
11
vim /etc/rc.local
/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
# 如果是 Ubuntu 16.04 以上,rc.local 被当成了服务,而且默认是不会启动,需要手动启用一下服务
# 启动rc.local服务:
ln -fs /lib/systemd/system/rc-local.service /etc/systemd/system/rc-local.service
systemctl cat rc.local
sudo systemctl enable rc-local.service
# 如果有图形桌面的话
super键--search "startup"-->设置开机启动选项,最重要的就是找到程序的绝对路经写上就可以.可以通过如下命令查看:
vim ~/.config/autostart/chromium-browser.desktop

使用systemd设置开机启动

systemd默认读取/etc/systemd/system下的配置文件,该目录下的文件会链接/lib/systemd/system/下的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo vim /lib/systemd/system/rslsync.service
[Unit]
Description=rslsync
After=network.target
[Service]
Type=forking
ExecStart=/home/femn/resilio-sync_glibc23_x64/rslsync
[Install]
WantedBy=multi-user.target
sudo chmod 754 /lib/systemd/system/rslsync.service
sudo systemctl start rslsync.service
sudo systemctl enable rslsync.service

也可以使用第三方包来管理启动程序

定时任务

1
2
3
4
5
6
7
8
9
10
11
12
13
vim /etc/crontab
# 权限要一致,且要可执行
# 分 时 日 月 周 命令
# 每天11点执行
0 11 * * * root sh /home/python/xx.sh
# 每两个小时
0 */2 * * * echo "Have a break now." >> /tmp/test.txt
# 晚上11点到早上8点之间每两个小时和早上八点
0 23-7/2,8 * * * echo "Have a good dream" >> /tmp/test.txt
# 保存退出即生效(刚添加的任务会到2-3分钟后才开始生效)

查看服务状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ubuntu centos
service sshd status/stop/restart # service 在rc*.d/的名字
systemctl start docker #centos启动服务
systemctl enable docker # 开机启动
systemctl status nginx
systemctl start firewalld.service
systemctl enable firewalld.service
systemctl daemon-reload # 修改启动参数时的
systemctl restart docker
# 只有systmectl 状态 服务名
# redhat 操作系统下
chkconfig 命令
chkconfig --list sshd

进程有关的

“衍生出来的进程”正是 Linux 的父子进程的概念.
当我们登录系统后,会取得一个 bash shell,然后我们利用这个 bash 提供的接口去执行另一个命令,

例如 bash 或者 ps 等.那些另外执行的命令也会被触发成为 PID,那个后来执行的命令产生的 PID 就是”子进程”,而原本的 bash 环境下,就称为”父进程”了

1
2
3
4
5
6
7
8
9
10
11
12
bash
ps -o pid,ppid,tty,time,cmd
PID PPID TT TIME CMD
11373 4396 pts/12 00:00:00 bash
13043 11373 pts/12 00:00:00 bash
13110 13043 pts/12 00:00:00 ps -o pid,ppid,tty,time,cmd
PID: 运行着的命令(CMD)的进程编号
PPID:父进程号
TTY: 命令所运行的位置(终端)
TIME: 运行着的该命令所占用的CPU处理时间
CMD: 该进程所运行的命令
# ps 仅仅显示本终端的进程

我所做的操作是在原来的 bash shell 中执行了 bash 命令,然后又执行了 ps -o pid,ppid,comm命令.我们可以看到
,第二个进程 bash 是第一个进程 bash 的子进程,而第三个进程ps是第二个进程的子进程

新的进程要通过老的进程复制自身得到,这就是 fork.fork 是一个系统调用.
进程存活于内存中.每个进程都在内存中分配有属于自己的一片空间 (内存空间,包含栈、堆、全局静态区、文本常量区、程序代码区).

当一个程序调用 fork 的时候,实际上就是将上面的内存空间,又复制出来一个,构成一个新的进程,
并在内核中为该进程创建新的附加信息 (比如新的 PID,而 PPID 为原进程的 PID).此后,两个进程分别地继续运行下去.
新的进程和原有进程有相同的运行状态(相同的变量值,相同的指令…).我们只能通过进程的附加信息来区分两者.

工作管理(job control)

是用在 bash 环境下的,也就是说,当我们登录系统取得 bash shell 之后,在单一终端机下可以同时进行多个工作的行为管理.

假如我们只有一个终端,因此在可以出现提示符让你操作的环境就成为前台(foreground),至于其他工作就可以放在后台(background)去暂停或运行
程序调用 exec 的时候,进程清空自身的内存空间,并根据新的程序文件重建程序代码、文本常量、全局静态、堆和栈(此时堆和栈大小都为 0),并开始运行.

直接将命令放到后台执行 ( &)

将目前工作放到后台并暂停(ctrl+z)

将后台工作拿到前台来处理(fg %工作序号)

进程管理命令

ps: PID,CMD,PORT

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
ps # 仅仅显示本终端的进程
-a # 显示终端中进行的所有进程
-x # 会显示没有控制终端的进程
-e # 所有的进程
-u # 查看某个用户的所有进程
-f # 来查看格式化的信息列表
ps -u femn # 查看所有femn用户的进程
ps aux # 可以对系统进程更加全面的了解
ps -aux | less
# less是一个分页显示文件的工具工具,它允许你一页一页(或一个屏幕一个屏幕)地查看信息
ps -ef # 所有进程 PID PPID
ps -efH # 把输出的进程组成一个层级的格式 树状
ps axjf # 树状视图 等于 pstree
ps -ef | grep python3 | cut -c 10-15 | xargs kill -9
# Kill 某个用户或命令的所有进程
ps axjf |grep nginx
pgrep nginx # 单单的得到PID,和其子进程号
ps -aux --sort -pcpu | head -n 10
# 根据 CPU 使用来升序排序 +pcpu倒序
ps -aux --sort -pmem | head -n 10
# 根据 内存 使用来升序排序
ps -aux --sort -pcpu,-pmem | head -n 10
# 仅仅得到本机的程序名相关的进程
ps aux/-ef |grep ssserver # 程序名(命令名)或者PID

netstat:PID,CMD,PORT

1
2
3
4
5
6
7
8
# 会牵扯到此程序 相关联的socket服务,或其它的网络相接进程(网络是双向的)
netstat -anp |grep ssh #程序名 得到PID 端口号
netstat -lnp |grep 8388 #端口号 得到PID,进程名
sudo lsof -i :8001 #查看此端口 PID,User,进程名
ll /proc/进程号
sudo lsof -p 1609
killall http* 它支持通过进程名而不是进程号来结束进程,也支持通配符.

top

1
2
3
4
5
6
top # 动态显示进程 q 退出, M 内存占用降序排序,P 按CPU占用降序排序
[top使用说明](http://www.linuxidc.com/Linux/2011-03/33582.htm)
ssserver内存占用随时间升高
free -m # 内在的使用情况
# 查看目前进程正在实际被使用的内存,是used-(buffers+cache)
htop # 更加友好的显示top

进程的状态

sleeping

D(sleeping),往往是由于 I/O(磁盘IO,网络IO,其他外设IO) 资源得不到满足,而引发等待

举个例子,当 NFS 服务端关闭之时,若未事先 umount 相关目录,在 NFS 客户端执行 df 就会挂住整个登录会话,按 Ctrl+C 、Ctrl+Z 都无济于事.
断开连接再登录,执行 ps axf 则看到刚才的 df 进程状态位已变成了 D ,kill -9 无法杀灭.

正确的处理方式,是马上恢复 NFS 服务端,再度提供服务,刚才挂起的 df 进程发现了其苦苦等待的资源,便完成任务,自动消亡.若 NFS 服务端无法恢复服务,在 reboot 之前也应将 /etc/mtab 里的相关 NFS mount 项删除,以免 reboot 过程例行调用 netfs stop 时再次发生等待资源,导致系统重启过程挂起.

zombile

Z(zombie) 之所以杀不死,是因为它已经死了,否则怎么叫 Zombie(僵尸).在UNIX/Linux中,每个进程都有一个父进程,进程号叫PID(Process ID), 相应地,父进程号就叫PPID(Parent PID).

当进程死亡时,它会自动关闭已打开的文件,舍弃已占用的内存、交换空间等等系统资源,然后向其父进程返回一个退出状态值,报告死讯.如果程序有 bug,就会在这最后一步出问题.子进程说我死了,父进程却没听见,所以子进程便成了僵尸.在UNIX/Linux中消灭僵尸的手段比较残忍,执行 ps axjf 找出僵尸进程的父进程号(PPID,第一列),先杀其父,然后再由进程天子 init(其PID为1,PPID为0)来一起收拾父子僵尸.注意,子进程变成僵尸只是碍眼而已,并不碍事,如果僵尸的父进程当前有要务在身,则千万不可贸然杀之.

这些进程已经死亡,但没有释放系统资源,包括内存和一些一些系统表等,如果这样的进程很多,会引发系统问题.用ps -el看出的进程状态如果是Z,就是僵尸进程.

1
2
3
4
5
ps -ef|grep defunc # 可以找出僵尸进程
# 清除ZOMBIE(僵尸)进程可以使用如下方法:
kill –18 PPID (PPID是其父进程)
# 这个信号是告诉父进程,该子进程已经死亡了,请收回分配给他的资源.

如果不行则看能否终止其父进程(如果其父进程不需要的话).先看其父进程又无其他子进程,如果有,可能需要先kill其他子进程,也就是兄弟进程.方法是:

1
2
kill –15 PID1 PID2 # (PID1,PID2是僵尸进程的父进程的其它子进程).
kill –15 PPID # 然后再kill父进程,这样僵尸进程就可能被完全杀掉了

Share Comments

内容分发网络

CDN:

内容分发网络(Content delivery network或Content distribution network,缩写:CDN)是指一种通过互联网互相连接的电脑网络系统,
利用最靠近每位用户的服务器,更快、更可靠地将音乐、图片、视频、应用程序及其他文件发送给用户,来提供高性能、可扩展性及低成本的网络内容传递给用户

CDN的作用

1.加速您网站的访问:

访问者的每个访问请求,都会被自动发送到物理距离最近、速度最快的节点上.
将blog内容的所有的东西(图片,文字,视频)都是保存在自己的服务器中,要从自己的服务器中取得,当如果某个页面需要加载很多内容时,速度就会变慢.
而cdn就会把所以网址上的东西,全部分送到它们在全世界各地所架设的云端的伺服务器上,也就是说我的网址会被散播(拆解)到全世界的伺服务器上,取最近的.

2.防骇客,抵御DoS攻击,访问我们的网址,相当于访问到云端的伺服务器上.

3.可以承受网站的流量,节省您的流量:

您的网站内容将被缓存在 CloudFlare 的节点中,访问者并不直接从您的主机获取内容,从而最大限度地节省主机的流量
同时网站的下载速度也会比以往的快些.

使用cloudflare加速

cloudflare是一个国外著名的免费CDN网站加速服务公司
甚至可以在网站主服务器宕机的情况下,访问者依然可以通过 CloudFlare 的分发服务器访问到您的网站

使用cloudflare的教程

但使用了cloudflare之后,就不再支持泛域名的解析了,所以还得多配置nginx.

Share Comments

sshd

server

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
sudo apt-get install openssh-server
ps ef|grep ssh
sudo /etc/init.d/ssh start 或者 service sshd start
# 创建一个普通用户
useradd username
passwd username
vim /etc/ssh/sshd_config
Port 22333
PermitRootLogin no
TCPKeepAlive yes
ClientAliveInterval 360
ClientAliveCountMax 20
# 给普通用户附sudo权限
chmod u+w /etc/sudoers
vim /etc/sudoers
root ALL=(ALL) ALL
username ALL=(ALL) ALL
chmod u-w /etc/sudoers
/etc/init.d/ssh start
service sshd restart
firewall-cmd --permanent --add-port=22333/tcp
firewall-cmd --reload

client

1
ssh -p 22333 username@ip

SSH无密码登录

1
2
3
4
5
6
7
8
9
# client:生成SSH公钥
ssh-keygen -t rsa -C "邮箱"
# 将SSH公钥上传到Linux服务器
ssh-copy-id -p 22 username@remote-server
# 将client端的gedit ~/.ssh/id_rsa.pub的内容放到server端~/.ssh/authorized_keys
# 等同于如下
cat ~/.ssh/id_rsa.pub | ssh username@your_host \
"cat - >> /home/username/.ssh/authorized_keys"
Share Comments

shadowsocks

  • 安装蓝灯官方地址 ,github地址

    Windows、Linux、macOS、Android

    安装启动即可,会自动去设置代理,不过每月只有500M免费流量

    代理端口 HTTP(S):40427 ,SOCKS5:42409

  • 安装XX-net + SwitchyOmega

    Windows、Linux、macOS、Android

    代理端口 HTTP:8087 ,SOCKS5:1080

    安装使用

    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
    # 注意/etc/resolv.conf nameserver 8.8.8.8 才能下载
    sudo apt-get install miredo
    # 测试是否已经开启IPV6
    ping6 ipv6.google.com
    # 解压缩后运行 start.sh就可以
    # 配置http代理 localhost 8087, 勾选全部协议使用这个代理
    # 使用 SwitchOmega 四种模式
    /home/femn/Downloads/XX-Net-3.8.7/SwitchyOmega/OmegaOptions.bak 导入到 SwitchyOmega插件上
    # 证书不被信任,所以要将xx-net的证书导入到chrome中
    chrome://settings/certificates --> Authorities
    -->/home/femn/Downloads/XX-Net-3.8.7/data/gae_proxy/CA.crt
    cd /home/femn/Downloads/XX-Net-3.8.7
    ./start
    # 会自动打开Web管理界面 http://127.0.0.1:8085/ 我是重启电脑之后再运行再出现的
    # 每个AppID每天1G流量,一般每个Google帐户最多12个AppID
    先创建6个APPID https://github.com/XX-net/XX-Net/wiki/how-to-create-my-appids
    # integral-kiln-190309|xx-net2-190400|xx-net3-190400|xx-net4-190400|xx-net5-190400|xx-net6-190400
    然后再去 http://127.0.0.1:8085/?module=gae_proxy&menu=deploy 部署以及配置
    # 注意要一定运行 miredo
    # 而且要查看 SwitchyOmega GAE-Proxy自动切换和X-Tunnel自动切换两种模式 是否设置成AutoProxy
    # 导入进来的有四种模式 当有些不能用时 就换别的
  • shadowsocks 官网

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
yum install python-setuptools && easy_install pip
pip install shadowsocks
vim /root/ss/ssserver.json
{
"server": "0.0.0.0",
"server_port": 8388,
"local_address": "127.0.0.1",
"local_port": 1081,
"password": "yourpassword",
"timeout": 300,
"method": "aes-256-cfb",
"fast_open": false
}
systemctl start firewalld.service
systemctl enable firewalld.service
firewall-cmd --permanent --add-port=8388/tcp
firewall-cmd --reload
# 启动 ssserver服务
nohup ssserver -c /root/ss/ssserver.json -d start &
# 查看ssserver 有没有启动成功
ps aux |grep ssserver
# 状态要是Ss,必须要切换到root用户执行

如果没有成功,可能是因为/root/ss/ssserver.json 的server_ip的原因,我买了个国际阿里云的ECS服务器,我写的是公网的IP,结果一直运行不起来
因为公网是通过nat IP实现的(所以在安全组中只能是选择内网进行配置),所以改成Privaty IP就可以正常启动了,最好是设置为0.0.0.0就好.

阿里云的ECS服务器上配置使用任意端口的服务后,端口会自动开启监听,但它还有一个安全组的概念,最好设置一个(内网 入 允许 全部 -1/-1 0.0.0.0/0 优先级110)
这样就完全可以由ECS的系统完全的操作防火墙,就像没有安全组概念一样了.

server_centos7 install BBR 要注意下sudo grub2-set-default 0,应该是为0的,使用最新的,文档却写成了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
# update kernet
# look current kernet
uname -r
# Install the ELRepo repo:
sudo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
sudo rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
# install newer kernet
sudo yum --enablerepo=elrepo-kernel install kernel-ml -y
# look install newer kernet
rpm -qa | grep kernel
sudo egrep ^menuentry /etc/grub2.cfg | cut -f 2 -d \'
# setting newer kernet
sudo grub2-set-default 0
sudo shutdown -r now
uname -r
# enable BBr
echo 'net.core.default_qdisc=fq' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv4.tcp_congestion_control=bbr' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
sudo sysctl net.ipv4.tcp_available_congestion_control
net.ipv4.tcp_available_congestion_control = bbr cubic reno
sudo sysctl -n net.ipv4.tcp_congestion_control
bbr
lsmod |grep bbr # output tcp_bbr 16384 0

1
2
3
4
5
6
#ubuntu
sudo add-apt-repository ppa:hzwhuang/ss-qt5
sudo apt-get update
sudo apt-get install shadowsocks-qt5
ss-qt5
# 将ssserver.json的配置,设置到ss中

注意:一定要再去配置下代理Pxory 0.0.0.0:1081 或者用本地的.pac文件,Local Port就必须和service.pac文件(此文件是过滤网址用的,如果访问文件中的网址则走代理)启动的端口一致.

http://pac.ddcc.me/1.pac == local.pac

在国际里云购买的ESC,配置好shadowsocks之后,在手机上能正常使用,也不需要去设置代理,但在Ubuntu桌面下却一直用不了

  • 推荐安装SSR是SS的高级版本

server端

1
2
3
4
5
6
7
# Debian 7x64 系统中的安装
wget --no-check-certificate -O shadowsocks-all.sh https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-all.sh
chmod +x shadowsocks-all.sh
./shadowsocks-all.sh 2>&1 | tee shadowsocks-all.log
# 然后会提示你输入数字选择,第一个选2(输入2后回车)第二自己输入一个SSR的密码
# 第三输入一个端口(端口范围1--65536,推荐10000以上,默认的138可能在手机上用不了)
# 第四选12,第五选3,第六选2

ssr_client端

1
2
3
4
5
6
7
8
9
cd
tar -zxvf electron-ssr-0.1.2.tar.gz
git clone https://github.com/shadowsocksrr/shadowsocksr.git
cd shadowsocksr
bash initcfg.sh
cd ~/electron-ssr-0.1.2
./electron-ssr
# 路径为:/home/femn/shadowsocksr/shadowsocks/local.py
# 版本为Python 3.6.3 :: Anaconda, Inc.

  • 安装I2P 最大下载速度只有 10 KB/s 左右

    代理端口 HTTP:4444, https:4445

1
2
3
4
5
6
7
8
9
10
11
12
# 此命令将添加 PPA 至 /etc/apt/source.list.d 中
# 并获取软件源签名所使用的 GPG 密钥.GPG 密钥保证软件包自编译后没有被篡改
# 输入一下命令,通知您的软件包管理器新添加的PPA源:
sudo apt-add-repository ppa:i2p-maintainers/i2p
# 此命令将从系统中已启用的每个软件源中获取最新的软件列表,包括刚刚通过命令添加的 I2P PPA 源.
sudo apt-get update
sudo apt-get install i2p
# 启动 i2prouter脚本,用图形自启
i2prouter start
# 作为服务在您的系统启动时自动运行,甚至早于用户登录
sudo dpkg-reconfigure i3p

补种

首次安装时,请不要忘记如果可能请调整您的 NAT/防火墙. 需要转发的端口可以通过路由控制台的 网络配置页面查看. 如果需要端口转发/端口映射方面的帮助,portforward.com可能会对您有用

请到配置页面, 检查并调整带宽设置,因为默认设置的 96 KB/s 下行 / 40 KB/s 上行相当保守

如果您希望通过浏览器访问I2P暗网内的网站, 您需要参看 浏览器代理设置 页面了解基本设置方法

安装proxychains4,使其在命令行中使用代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
git clone https://github.com/rofl0r/proxychains-ng.git
cd proxychains-ng
./configure --prefix=/usr --sysconfdir=/etc
# /usr/bin/proxychains4 /etc/proxychains.conf
make && make install
make install-config
cd .. && rm -rf proxychains-ng
echo -e "strict_chain\n\
proxy_dns\n\
remote_dns_subnet 224\n\
tcp_read_time_out 15000\n\
tcp_connect_time_out 8000\n\
localnet 127.0.0.0/255.0.0.0\n\
[ProxyList]\n\
socks5 127.0.0.1 1081"\
> /etc/proxychains.conf
# 查看代理是否成功
curl ip.gs
proxychains4 curl ip.gs

Resilio Sync原名:BitTorrent Sync

是一款跨平台的文件同步工具,让你在几台不同的设备之间,同步文件,文件不经过任何云端服务器,文件只在客户端之间直接传输,十分安全私密.正是因为这一点,因此很快成为文件共享的热门应用,大家既可以配合 VPS,用它来搭建一个网盘,也可以借助他的共享能力用来和朋友共享文件

启动

1
2
3
4
5
6
# 下载此包并解压
wget https://download-cdn.resilio.com/stable/linux-x64/resilio-sync_x64.tar.gz
# 运行
./rslsync
# 本机浏览器中访问地址127.0.0.1:8888
# 进入Resilio Sync管理页面.当然,这个端口号是可以修改的,在配置文件/etc/resilio-sync/config.json

作为网盘

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name sync.yourdomain.com;
access_log /var/log/nginx/sync.yourdomain.com.log;
location / {
proxy_pass http://127.0.0.1:8888;
}
}

ubuntu /etc/resolv.conf

1
2
3
nameserver 127.0.1.1
# nameserver 8.8.8.8
search DHCP HOST
Share Comments