Vim 全局命令 g

全局命令 :g 在 Vim 中有着意想不到强大的功能。当想要在整个文件中对于匹配的行或者不匹配行进行一些操作时,应该第一时间想到这个 :g 命令。

:[range]global[!]/{pattern}/{command}

简写可以写成

:[range]g/pattern/command
  • [range] 指定文本范围,默认为整个文档
  • pattern 在范围 range 内的行如果匹配 pattern,则执行 command
  • ! 表示取反,也就是不匹配的行,也可以使用 vglobal
  • command 默认是打印文本

整个命令可以理解成,在 range 范围内匹配 patter 的行执行 Ex command。所有的 Ex command 可以使用 :help ex-cmd 来查看。

常用的 Ex command 可以参考如下例子:

  • d 删除
  • m 移动
  • t 拷贝
  • s 替换

举例

范围匹配

比如在 20 行到 200 行之间,每一行下插入空行

:20,200g/^/pu _

删除匹配的行

最简单的使用

:g/pattern/d

会删除 pattern 批量的行,再比如

:g/^$/d

可以用来删除空白行。

删除不匹配的行

匹配使用 :g ,而不匹配有两种写法:

:g!/pattern/d
:v/pattern/d

:v:in(v)erse 的缩写,如果为了记忆的话,可以记住 inverse。

删除大量匹配行

Vim 在删除操作时,会先把要删除的内容放到寄存器中,假如没有指定寄存器,会默认放到一个未命名的寄存器中,对于要删除大量匹配行的行为,可能导致 Vim 花一些时间处理这些拷贝,避免花费不必要的时间可以指定一个 blackhole 寄存器 _

:g/pattern/d_

移动匹配的行

将所有匹配的行移动到文件的末尾

:g/pattern/m$

复制匹配的行

将所有匹配的行复制到文件末尾

:g/pattern/t$

复制到 register a

Vim 每个字母都是一个寄存器,所以使用全局命令也可以将内容复制到某一个寄存器,比如 a

qaq:g/pattern/y A
  • qaq 清空寄存器 a,qa 开始记录命令到a寄存器,q 停止记录
  • y A 将匹配的行 A (append) 追加到寄存器 a 中

存放到 a 寄存器之后就可以使用 "ap 来粘贴使用或者其他操作了。

反转文件中的每一行

just show the power of :g

:g/^/m0

:g 命令一行行匹配,匹配第一行时将第一行 m0 放到文件顶部,第二行放到文件顶部,当跑完一遍之后整个文件的每一行就反转了。

在匹配行后添加文字

使用 s 命令可以实现,同样使用全局 g 命令也可以实现同样的效果

:g/pattern/s/$/mytext

这里使用到了 s 命令, substitute 命令,可以使用 :help :s 来查看。

reference


2017-10-29 Vim , Regex , Linux

kibana query syntax

Kibana 的查询语法基于 Lucene 的查询语法,他允许 boolean 值,通配符,过滤器等等操作。

字符串查询

通常一个查询会包含一个或者多个单词或者组合。一个简单的查询语句就是用引号包含的一组词,比如 “search demo”.

如果不包含双引号,Kibana 会单独的去匹配每一个词。

正则表达式查询

大部分正则表达式是允许匹配部分字符的,然而在 Lucene 中,正则表达式用来匹配整个字符串,比如 abcde 这个字符串

  • 使用 ab.* 能够匹配
  • 但是使用 abcd 是不能匹配的

正则表达式中,有一些保留字符

. ? + * | { } [ ] ( ) " \

这些字符如果出现在表达式中都需要进行转义,比如 \* ,或者 \\

这些符号的含义和正则表达式一致

  • . 用来表示任意字符
  • ? 用来表示前面的字符重复一次或零次
  • + 表示前面的字符重复一次或多次
  • * 表示前面的字符重复零次或多次
  • {n} 表示重复n次
  • {n,m} 表示重复n到m次
  • () 表示 group, 组合其他使用
  • | 表示 OR 或者,(http|https) http 或者 https 匹配
  • [] 表示括号中的任意一个

更多的关于正则表达式的内容可以参考任意一本关于正则的书。

补充,在 Kibana 中如下字符都需要转义

+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /

比如查询 (1+1)=2 需要使用 \(1\+1\)\=2

可选表达式

Lucene 中还能够开启一些扩展操作。

Complement 模式

比如 ab~cd 可以表示字符串以 ab 开始接着跟随一个任意长度非c字符,以d结尾的字符串。

Interval

使用 <> 来匹配数字范围, 比如 foo<1-100> 可以匹配string foo90 却不能匹配 foo101

Intersection

符号 & 用来连接两个 patterns 两个正则表达式都需要匹配

Any string

符号 @ 用来匹配所有,和 Intersection 联合使用可以用来表示,匹配所有除了。

比如 @&~(foo.*) 用来匹配所有字符,除了以 foo 开头的字符

范围查询

范围查询用来查询一定范围的匹配,比如

ResponseTime: [10 TO *]

用来查询请求时间大于等于 10 ms 的,或者使用 ResponseTime: {10 TO *} 来匹配大于 10 ms 的。

方括号可以表示包括,花括号不包括,所以 [10 TO 50} 表示 需要 10<=value<50

也可以简化写成

age:(>=10 AND <50)

这样

Boolean 查询

逻辑运算 AND、OR、NOT 可以用来组合查询语句,这三个运算符必须 大写 ,更多内容可以查看 Lucene 语法。

  • + 搜索结果中必须包含此项
  • - 不能含有此项

字段名称搜索

比如需要查询 statusactive 的内容,可以

status:active

近似搜索

在短语后面加 ~ 可以搜到被隔开或者顺序不同的单词。

比如 “where select”~5, 表示 select 和 where 中间可以相隔5个单词。

reference


2017-10-29

每天学习一个命令:代码搜索工具 ack-grep

ack 是一个代码搜索工具,作者 厌烦了 grep 复杂的语法,所以创造了 ack 来解决痛点。ack 使用 Perl 语言开发,使用友好,速度快。ack 在大量代码文件中的搜索效率极高。

安装

sudo apt-get install ack-grep

使用

文本搜索

默认情况下 ack-grep 会搜索当前目录下所有文件内容,只要包含关键字就会输出。

ack-grep keyword
ack-grep -l keyword     # 只显示文件名
ack-grep -i keyword     # 忽略大小写
ack-grep -w keyword     # 强制要求 PATTERN 匹配整个单词

查找文件

可以代替 find 加 grep,其实 ack 的 -f 选项表示的是打印所有将要被搜索的文件,事实上不会执行搜索,如果后面加 PATTERN ,那么就在路径中搜索文件名。-g 选项表示的是搜索当前路径下的符合 PATTERN 的文件。

ack-grep -f filename
ack-grep -g file*

过滤文件

可以使用 --python 选项来指定在 python 文件中搜索

ack-grep --python keyword

reference


2017-10-26 ack , linux , command

Nginx 反向代理 Google 配置

使用编译安装 Nginx,将 ngx_http_substitutions_filter_modulengx_http_google_filter_module 两个模块编译进 Nginx。具体内容可以参考安装篇。

对于 Nginx 基本设置可以参考 配置篇 .

这篇主要演示 Nginx 作为一个反向代理服务器的基本设置。

Nginx 反向代理最重要的一个配置就是 proxy_pass ,该配置接受一个参数, URL ,也就是 Nginx 转发的目的地。Nginx 会自动将请求的 URI 替换为 proxy_pass 配置的 URI。

location /uri {
    proxy_pass http://localhost:8083/newUri;
}

常用配置

反代相关配置

反向代理的常用配置选项

Directive Explanation
proxy_connect_timeout 向上游服务器请求超时时间
proxy_cookie_domain 将请求头中 Set-Cookie 头内容替换成新域名
proxy_cookie_path 替换 Set-Cookie 中路径
proxy_headers_hash_bucket_size 请求头名最大size
proxy_headers_hash_max_size 从上游服务器接收到的所有 headers 总量
proxy_hide_header 一组不会被传给 client 的 headers
proxy_http_version 和上游服务器通信使用的 HTTP 协议版本
proxy_ignore_client_abort 如果设置为 on, Nginx 在client 停止请求时不会停止向上游服务器请求
proxy_ignore_headers 处理上游服务器返回时设置一组不处理 headers
proxy_intercept_errors 设置开启, Nginx 将显示 error_page 配置的错误而不会向上游服务器请求
proxy_max_temp_file_size The maximum size of the overflow file, written when the response doesn’t fit into memory buffers.
proxy_pass 上游服务器 URL
proxy_pass_header 覆盖被 proxy_hide_header 配置禁用的 headers,允许他们发送给客户端
proxy_pass_request_body off 时阻止向上游服务器发送请求body
proxy_pass_request_headers off 时阻止向上游服务器发送 headers
proxy_read_timeout 连接关闭前,向上游服务器两次读成功耗时
proxy_redirect Rewrites the Location and Refresh headers received from the upstream servers; useful for working around assumptions made by an application framework.
proxy_send_timeout 连接关闭前,向上游服务器两次写成功耗时
proxy_set_body 修改请求body
proxy_set_header 修改请求 headers
proxy_temp_file_write_size 限制单个请求的临时文件大小, Nginx 不会在一个请求上被 block
proxy_temp_path 临时文件地址

upstream 选项中的配置

Directive Explanation
ip_hash 使得客户端的请求能够均匀的分布
keepalive 每一个 worker process 向上游服务器请求缓存的连接数,proxy_http_version 需要设置为 1.1 并且 proxy_set_header 设置为空
least_conn 负载均衡算法,根据 active 连接数来选择下一个连接
server 设置地址,域名或者 IP,或者 Unix-domain socket 一些选项 weight: 设置 server 的权重,max_fails: 重试最大次数,fail_timeout: 服务器超过该时间会被标记为 Down ,backup: 只有其他机器都 Down 情况下才会使用该服务器,down: 标记为 down 不会处理请求

示例

keep alive

以如下配置示例

upstream apache {
	server 127.0.0.1:8080;
	keepalive 32;
}
location / {
	proxy_http_version 1.1;
	proxy_set_header Connection "";
	proxy_pass http://apache;
}

假设定义了 apache upstream ,使用 Nginx 转发到本地 8080 端口, 设置了 keepalive 为 32。每一个 Nginx worker 只会在最初始化时TCP握手建立32个连接,Nginx 会保存连接,不会发送 close

如果需要超过 32 个连接, Nginx 会再新建连接满足需求,如果需求降低, Nginx 会自动将超过 32 个连接的请求,按照最近使用的连接关闭,直到将连接数降到 32 。

负载均衡算法

upstream 模块会使用三种算法来选择向哪一台上游服务器建立连接—- round-robin, IP hash, 或者是 least connections.

round-robin 算法是默认值,算法根据上一次选择的服务器决定下一次选择哪一条连接,算法公平的根据 turn by turn 的方式来保持平衡。

IP hash 算法,需要通过 ip_hash 指令开启 Nginx 使用 IPv4 地址的前三个字节或者是整个 IPv6 地址作为 hashing key 。因此一组IP地址永远被map到特定的上游服务器。因此这个机制不是设计为均匀分发请求,而是被设计成将客户端和上游服务器映射到一起。

第三种负载均衡算法叫做 least connections , 通过 least_conn 开启。该算法设计成将负载均匀的打到上游服务器中,通过选择活跃连接数最小的服务器。如果上游服务器不是具有相同的处理能力,可以通过指定 weight 来人为处理。算法会将不同 weight 的服务器纳入计算活跃连接数的考虑范畴。

创建 Google 的反向代理

创建一个 Ngixn 虚拟主机,我使用 https://g.einverne.info 来演示:

# 配置 google ip 地址,使用 nslookup google.com 来获取 Google 服务器地址,避免 Google 机器人检测
upstream www.google.com {
    server XXX.XXX.XXX.XXX:443 weight=1; #把XXX替换成可用 IP
    server XXX.XXX.XXX.XXX:443 weight=1;
    server XXX.XXX.XXX.XXX:443 weight=1;
    server XXX.XXX.XXX.XXX:443 weight=1;
    server XXX.XXX.XXX.XXX:443 weight=1;
    server XXX.XXX.XXX.XXX:443 weight=1;
    server 216.58.216.163:443 weight=1; #hk
}

server {
    listen 80;
    listen [::]:80;
    server_name g.einverne.info;

    listen 443 ssl;
	ssl_certificate path_to_ssl_crt; # 证书
	ssl_certificate_key path_key; # key

	# 自动 http 转 https
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }

    if ($http_user_agent ~* (baiduspider|360spider|haosouspider|googlebot|soso|bing|sogou|yahoo|sohu-search|yodao|YoudaoBot|robozilla|msnbot|MJ12bot|NHN|Twiceler)) {
        return  403;
    }

	# 编译时加入 ngx_http_google_filter_module 模块,location 如下设置
    location / {
        google on;
    }

    access_log /var/log/nginx/g.einverne.info.access.log;
	error_log /var/log/nginx/g.einverne.info.error.log;
}

如果编译时没有加入 ngx_http_google_filter_module 模块,则需要设置 location

location / {
	proxy_redirect off;
	proxy_cookie_domain google.com <domain.name>; 
	proxy_pass https://www.google.com;
	proxy_connect_timeout 60s;
	proxy_read_timeout 5400s;
	proxy_send_timeout 5400s;

	proxy_set_header Host "www.google.com";
	proxy_set_header User-Agent $http_user_agent;
	proxy_set_header Referer https://www.google.com;
	proxy_set_header Accept-Encoding "";
	proxy_set_header X-Real-IP $remote_addr; 
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
	proxy_set_header X-Forwarded-Proto https;
	proxy_set_header Accept-Language "zh-CN";
	proxy_set_header Cookie "PREF=ID=047808f19f6de346:U=0f62f33dd8549d11:FF=2:LD=en-US:NW=1:TM=1325338577:LM=1332142444:GM=1:SG=2:S=rE0SyJh2W1IQ-Maw";

	subs_filter https://www.google.com.hk <domain.name>;
	subs_filter https://www.google.com <domain.name>;
	#subs_filter_types text/css text/xml text/javascript;

	sub_filter_once off; 
}
  • proxy_redirect 设置为 off ,不需要重写 Location 的 header
  • proxy-cookie-domain google <domain.name>; 将cookie作用域替换成自己的域名
  • proxy_pass https://www.google.com; 反向代理到 upstream www.google.com
  • proxy_set_header Accept-Encoding ""; 防止谷歌返回压缩的内容,否则内容无法替换
  • proxy_set_header Cookie 这一行 禁止即时搜索,设置为新窗口打开网站
  • subs_filter https://www.google.com <domain.name>; 把Google域名替换,需要编译时加上 --with-http_sub_module 参数

reference


2017-10-25 linux , nginx , web , proxy , google

Nginx 配置详解

Nginx 的相关介绍及安装可以参考之前的一篇文章

Nginx 相关的配置, Nginx 中的配置有两种分类,一种为单纯的指令 (directive),另一种为上下文配置块 (configuration context)。

指令 (directive),包含名称参数名,以分号结束,比如

gzip on;

上下文通常声明一个作用域,比如 server 块

server {
    listen 80;
}

在上下文中使用相同的指令时需要小心,一般子级上下文中的指令会覆盖父级中定义的值。

全局块

Nginx 的全局配置是影响整个 WEB 服务器的配置。

主要有以下几个

Directive Explanation
user worker process 在配置的 user and group 下运行
workr_processes 最多的 worker processes 数量,可支持并发数,通常的做法是指定和 CPU cores 数量一致
error_log log
pid file where the process ID of the main process is written
use 连接方式
worker_connections 连接数

配置用户用户组

设置用户的配置

user user [group];
  • user, 可运行 Nginx 服务器的用户
  • group, 指定可运行用户组

希望所有用户都可以启动 Nginx 进程,一种是直接注释该配置,或者

user nobody nobody;

Nginx 配置文件中,每一条配置都必须以分号结束。

配置 worker process 数

worker process 是 Nginx 并发关键所在,理论上 worker process 值越大,可支持并发数也越多,但实际也受到软件,操作系统,硬件(CPU 和磁盘)等资源的制约。

worker_processes number | auto;
  • number, 指定 Nginx 进程最多可产生的 worker process 数
  • auto Nginx 自动

PID 存放路径

Nginx 进程作为系统守护进程运行,在文件中保存当前运行程序主进程号,支持配置 PID

pid file_path;
  • file_path 为存放路径和文件名

错误日志路径

全局块、http 块 和 server 块都可以对 Nginx 日志进行配置

error_log file | stderr [debug | info | notice | warn | error |crit | alert | emerg];

Nginx 日志支持输出到文件 file, 或者标准错误输出 stderr.

日志级别可选,从低到高 debug, info, notice, warn, error, crit, alert, emerg ,需要注意的是 debug 需要编译时使用 --with-debug 开启。

引入其他配置

Nginx 提供 include 配置来引入其他文件

include file;
  • file 是要引入的配置文件,支持相对路径和正则匹配

最大连接数

设置每一个 worker process 同时开启的最大连接数

worker_connections number;

只能在 events 块中配置

定义 MIME TYPE 类型

浏览器使用 MIME Type 来区分不同的媒体类型, Nginx 作为 Web 服务器,必须能够识别前端请求的资源类型。

默认的配置中,可以使用两种方式来配置

include mime.types;
default_type application/octet-stream

第一种方式引用外部文件。

mime.types 文件

types {
	text/html                             html htm shtml;
	text/css                              css;
	text/xml                              xml;
	image/gif                             gif;
	image/jpeg                            jpeg jpg;
	application/javascript                js;
	application/atom+xml                  atom;
	application/rss+xml                   rss;

	text/mathml                           mml;
	text/plain                            txt;
	text/vnd.sun.j2me.app-descriptor      jad;
	text/vnd.wap.wml                      wml;
	text/x-component                      htc;

	image/png                             png;
	image/tiff                            tif tiff;
	image/vnd.wap.wbmp                    wbmp;
	image/x-icon                          ico;
	image/x-jng                           jng;
	image/x-ms-bmp                        bmp;
	image/svg+xml                         svg svgz;
	image/webp                            webp;

	application/font-woff                 woff;
	application/java-archive              jar war ear;
	application/json                      json;
	application/mac-binhex40              hqx;
	application/msword                    doc;
	application/pdf                       pdf;
	application/postscript                ps eps ai;
	application/rtf                       rtf;
	application/vnd.apple.mpegurl         m3u8;
	application/vnd.ms-excel              xls;
	application/vnd.ms-fontobject         eot;
	application/vnd.ms-powerpoint         ppt;
	application/vnd.wap.wmlc              wmlc;
	application/vnd.google-earth.kml+xml  kml;
	application/vnd.google-earth.kmz      kmz;
	application/x-7z-compressed           7z;
	application/x-cocoa                   cco;
	application/x-java-archive-diff       jardiff;
	application/x-java-jnlp-file          jnlp;
	application/x-makeself                run;
	application/x-perl                    pl pm;
	application/x-pilot                   prc pdb;
	application/x-rar-compressed          rar;
	application/x-redhat-package-manager  rpm;
	application/x-sea                     sea;
	application/x-shockwave-flash         swf;
	application/x-stuffit                 sit;
	application/x-tcl                     tcl tk;
	application/x-x509-ca-cert            der pem crt;
	application/x-xpinstall               xpi;
	application/xhtml+xml                 xhtml;
	application/xspf+xml                  xspf;
	application/zip                       zip;

	application/octet-stream              bin exe dll;
	application/octet-stream              deb;
	application/octet-stream              dmg;
	application/octet-stream              iso img;
	application/octet-stream              msi msp msm;

	application/vnd.openxmlformats-officedocument.wordprocessingml.document    docx;
	application/vnd.openxmlformats-officedocument.spreadsheetml.sheet          xlsx;
	application/vnd.openxmlformats-officedocument.presentationml.presentation  pptx;

	audio/midi                            mid midi kar;
	audio/mpeg                            mp3;
	audio/ogg                             ogg;
	audio/x-m4a                           m4a;
	audio/x-realaudio                     ra;

	video/3gpp                            3gpp 3gp;
	video/mp2t                            ts;
	video/mp4                             mp4;
	video/mpeg                            mpeg mpg;
	video/quicktime                       mov;
	video/webm                            webm;
	video/x-flv                           flv;
	video/x-m4v                           m4v;
	video/x-mng                           mng;
	video/x-ms-asf                        asx asf;
	video/x-ms-wmv                        wmv;
	video/x-msvideo                       avi;
}

文件中包含了浏览器能够识别的 MIME 类型,以及对应的文件后缀名。

第二种方式使用 default_type mime-type 直接配置。

Server section

自定义 Access 日志

error_log 不同的是,Nginx 进程运行时访问日志,由 Nginx 提供服务过程中应答前端请求的日志。

Nginx 服务器支持对服务日志的格式、大小、输出等进行配置,需要使用两个配置 access_loglog_format

access_log path [format [buffer=size]];
  • path, 配置服务日志的文件存放路径及名称
  • format 可选,自定义日志格式,也可以通过 log_format 配置指定好,直接引用格式名
  • size 临时存放日志的内存缓存区大小

如果要取消记录日志功能,使用

access_log off;

自定义日志格式

log_format name string ...;
  • name 格式字符串的名字,默认为 combined
  • string 自定义格式化字符串

示例,配置如下两行

log_format exampleLog '$remote_addr - [$time_local] $request '
					  '$status $body_bytes_sent '
					  '$http_referer $http_user_agent';

access_log /var/log/nginx/access.log exampleLog;

查看日志 tailf /var/log/nginx/access.log

47.88.236.38 - [24/Oct/2017:10:25:30 +0800] GET /post/2017/10/things-to-do-after-install-wordpress.html?ajax_load=page HTTP/1.1 200 6961 https://www.einverne.info/ Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36

可以查看到上面格式的日志,IP 本地时间 请求方法 请求路径 HTTP 状态 发送数据大小 以及 HTTP refer 和 User Agent.

配置连接超时时间

用户连接会话连接后, Nginx 服务器可以保持打开一段时间

keepalive_timeout timeout [header_timeout];
  • timeout 对连接的保持时间
  • header_timeout 可选,在 Response 头部 Keep-Alive 域设置超时时间

示例

keepalive_timeout 120s 100s;

设置单连接请求数上限

限制用户通过某一个连接向 Nginx 发送请求次数

keepalive_requests number;

虚拟主机配置

虚拟主机配置以 server 开头,server 内的配置都认为是 虚拟主机 配置。虚拟主机定义了一套由不同 server_name 配置区分的资源。虚拟主机一般由 listenserver_name 等一组配置决定。

配置网络监听

监听配置方法主要有三种:

第一种配置监听 IP 地址

listen address[:port] [default_server] [setfib=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [deferred] [accept_filter=filter] [bind] [ssl];

第二种配置监听端口

listen port [default_server] [setfib=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [ssl];

第三种配置 UNIX Domain Socket

listen unix:path [default_server] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ssl];
  • 使用 default_server 将虚拟主机地址设置为 address:port 为默认
  • setfib 不常用
  • backlog 设置监听函数 listen() 最多运行多少网络连接同时处于挂起状态
  • rcvbuf 监听 socket 接受缓存区大小
  • sndbuf 监听 socket 发送缓存区大小
  • ssl 会话使用 SSL 模式

配置虚拟主机名称

主机是指 server 块对外提供虚拟主机

server_name name ...;

名字就是域名,用空格隔开

server_name einverne.info www.einverne.info;

Nginx 规定第一个名称作为虚拟主机的主要名

name 中可以使用通配符 * ,但通配符只能放到首尾,name 中还能使用正则表达式,使用 ~ 开始

server_name ~^ww\d+\.einverne\.info$;

匹配 ww1.einverne.info 但不匹配 www.einverne.info

对于不同的匹配方式,Nginx 按照如下优先级选择虚拟主机

  • 准确匹配 server_name
  • 通配符在开始时匹配 server_name 成功
  • 通配符在结尾时匹配 server_name 成功
  • 正则表达式匹配

在以上四种匹配方式中,如果 server_name 被处于同一优先级匹配方式匹配多次成功,则首次匹配成功的虚拟主机处理请求。

基于 IP 的虚拟主机配置

不是很常用,暂时略

配置 location 块

location 指令在 virtual server 部分使用,用来比欧式 URI 怎么处理。

语法

location [ = | ~ | ~* | ^~ ] uri { ... }

其中,uri 变量是待匹配的请求字符串,可以是不含正则表达的字符串。

方括号中为可选项,不添加可选项时, Nginx 首先在 server 块多个 location 块中搜索是否有匹配,如果有多个匹配,就记录匹配度最高的一个。然后,Nginx 再用 location 块中的正则 uri 和请求匹配,当第一个正则匹配成功,结束搜索,并使用该 location 块处理请求,如果正则全部失败,则使用刚才记录的匹配度最高的 location 块处理该请求。

了解了 location 块匹配规则,再来看一下各个可选项的含义:

  • = 用于非正则 uri 前,要求字符串与 uri 严格匹配,如果匹配成功,则停止向下搜索,并立即处理此请求
  • ~ 表示该 uri 包含正则,并且区分大小写
  • ~* 表示 uri 包含正则,不区分大小写
  • ^~ 用于非正则 uri 前,Nginx 服务器找到标示 uri 和请求字符串匹配程度最高的 location 后立即使用该 location 处理请求,不再匹配 location 块的正则 url

如果 uri 包含正则,则必须使用 ~~* 。 而对于 ^~ 会对 uri 中的 urlencode 内容解码, %20 会被理解为空格。

配置请求的根目录

Nginx 接受到请求之后,在服务器指定目录中寻求资源

root path;

path 为 Nginx 接受到请求之后查找资源的根目录路径。 path 变量可以包含 Nginx 服务器预设的大多数变量,但要注意 $document_root$realpath_root 不可用。

该配置可以再 http 块、 server 块或者 location 块中进行配置。

更改 location 的 URI

在 location 块中,除了使用 root 命令指明请求处理根目录,还可以使用 alias 配置来改变 location 接收到的 URI 请求

alias path;

path 就是修改后的根路径。

示例

location ~ ^/data/(.+\.(htm|html)) $ {
	alias /var/www/data/$1;
}

当 location 块接收到 /data/index.html 请求时,匹配成功,根据 alias 配置, Nginx 在 /var/www/data/ 目录下找到 index.html 并响应请求。

关于 root 和 alias 的区别 可以参考这篇文章

设置网站默认首页

在用户发出请求时,请求地址可以不填写首页完整路径

index file ...;

设置错误页面

指定错误页面

error_page code ... [=[response]] uri
  • code 要处理的 HTTP 错误代码
  • response 可选项,将 code 指定的错误转化为新的错误代码 response
  • uri 错误页面的路径或者网站地址

示例

error_page 404 /404.html

基于 IP 配置 Nginx 访问权限

Nginx 支持两种途径的基本访问控制,一种是由 HTTP 标准模块的 ngx_http_access-modele 支持,通过 IP 来判断客户端是否拥有对 Nginx 的访问权限

allow 配置用于设置 Nginx 客户端 IP 访问

allow address | CIDR | all;
  • address 允许访问的客户端 IP,不支持同时设置多个
  • CIDR 允许访问的客户端 CIDR 地址, 202.112.18.23/25,前 32 位 IP 地址,后面 ”/25“ 表示前 25 位是网络,其余代表主机部分
  • all 代表允许所有客户端访问

deny 配置,顾名思义

deny address | CIDR | all;

参数含义同上

Nginx 对于访问控制权限是顺序匹配,如果匹配成功就不会继续向下解析。

配置密码设置 Nginx 访问权限

Nginx 支持 HTTP Basic Authentication 协议的认证,该协议是一种 HTTP 性质的认证办法,需要用户名和密码,认证失败的客户端不拥有访问 Nginx 服务器的权限。

开启或者关闭

auth_basic string | off;
  • string 开启该认证功能,并验证配置时显示的提示信息
  • off 关闭该功能

    auth_basic_user_file file;

其中 file 为密码文件的绝对路径

使用如下命令创建用户名密码到文件

printf "yourusername:$(openssl passwd -apr1)" > /etc/nginx/passwords

记住替换 yourusername ,该命令会在 /etc/nginx 目录下创建 passwords 文件,该文件的格式为

yourusername:passwordencrypt

也可以使用 htpasswd 命令来生成,绝大部分语言提供 crypt() 函数来对加密密码

htpasswd -c -d /etc/nginx/passwords yourusername

然后添加如下配置

server {
	# ...
	auth_basic "Protected";
	auth_basic_user_file passwords;
	# ...
}

反向代理配置

简单配置

server
{
	listen          80;
	server_name     g.einverne.info;
	location / {
		proxy_pass          http://www.google.com/;  #反代的域名
		proxy_redirect      off;
		proxy_set_header    X-Real-IP       $remote_addr;
		proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
	}
}

reference

  • Nginx 高性能 Web 服务器详解

2017-10-23 nginx , web , server , linux , proxy

Git commit 中使用 gpg 签名提交

Ubuntu 下,GnuPG 2.0 的支持都在 gnupg2 这个 packages 下,通过下面命令安装:

sudo apt-get install gnupg2

GitHub 要求使用 GnuPG 2.1 及以后的版本。

Mac 下安装使用

在 Mac 下需要安装:

brew install gnupg
brew link --overwrite gnupg
brew install pinentry-mac # 密码输入管理器

然后在 shell 配置 (.bashrc~/.zshrc) 中添加 export GPG_TTY=$(tty).

添加配置

echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
killall gpg-agent

然后可以通过 echo "test" | gpg --clearsign 来验证一下。

Mac 下应该会弹出 GUI 窗口进行密码验证。

然后不要忘记配置 git config:

git config --global gpg.program gpg        # 配置全局的 gpg
git config --global commit.gpgsign true    # 配置每一个 commit 都需要 gpg

这里需要注意的一点是 Mac 下命令还叫做 gpg,但是在 Linux 下是 gpg2.

生成 GPG 签名

使用如下命令生成签名:

gpg2 --full-gen-key
  1. 选择默认 RSA and RSA
  2. 推荐 4096
  3. 过期时间
  4. 相关信息包括 Real name, Email, Comment(comment 可以写一些标示)
  5. 密码

如果遇到尝试卡在生成签名的步骤,提示

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

可能需要安装 rng-tools

sudo apt install rng-tools

之后在执行上面的命令。

使用以下命令查看本地密钥

gpg2 --list-keys --keyid-format LONG

结果

/home/einverne/.gnupg/pubring.gpg
---------------------------
pub   rsa4096/F80B65AAAAAAAAAA 2018-01-31 [SC]
uid                 [ultimate] Ein Verne (co) <email@address>
sub   rsa4096/B63A4CAAAAAAAAAA 2018-01-31 [E]

将其中的第三行 sec 中 rsa4096 后面的 ID 记住,拷贝出来。

然后使用

gpg2 --armor --export ID | xclip -sel c

来获取 GPG KEY,拷贝 -----BEGIN PGP PUBLIC KEY BLOCK----------END PGP PUBLIC KEY BLOCK----- 之前,包括这两行的内容到 GitHub。

使用 | xclip -sel c 可以直接将命令输出结果拷贝到系统粘贴板。

配置 GPG

产生 GPG,并且已经添加到 GitHub 后台,那么需要本地配置,告诉 git 本地签名。查看本地 gpg

gpg2 --list-keys --keyid-format LONG

添加配置,这里记得使用公钥

# 设置 gitconfig 配置签名的公钥 key
git config --global user.signingkey F80B65AAAAAAAAAA
# 设置签名使用的 gpg 软件
git config --global gpg.program gpg2
# 默认全部签名
git config --global commit.gpgsign true

将 GPG 添加到 bashrc

echo 'export GPG_TTY=$(tty)' >> ~/.bashrc

签名 commit

在提交时使用 -S 选项

git commit -S -m your commit message

来本地签名提交

提交标签同理

git tag -s mytag

可以使用 -v 来验证

git tag -v mytag

其他常用的 gpg 命令

生成 gpg key

gpg2 --full-generate-key

列出本地所有公钥

gpg2 --list-keys

查看秘钥

gpg2 --list-secret-keys

删除 uid 私钥

gpg2 --delete-secret-keys [uid]

删除 uid 公钥

gpg2 --delete-keys [uid]

问题

使用过程中遇到的一些问题

提交 commit 时 failed to sign the data

git commit -S 时如果遇到:

gpg: signing failed: Operation cancelled
gpg: signing failed: Operation cancelled
error: gpg failed to sign the data
fatal: failed to write commit object

尝试

export GPG_TTY=$(tty)

强制每次 git 提交使用 gpg 加密

git config --global commit.gpgsign true

对应如果选择关闭就直接使用 false 即可。

导出私钥用于不同电脑之间同步

在一台电脑中生成的 gpg secret key 可以用于不同的电脑

  • 首先运行 gpg2 --list-secret-keys 来确认本机的私钥,需要记住私钥的 ID (在第二列)
  • 导出私钥 gpg2 --export-secret-keys $ID > my-private-key.asc
  • 拷贝私钥到目标机器 (scp)
  • 导入私钥 gpg2 --import my-private-key.asc

如果在第二台机器中已经有了公钥,私钥,那么需要分别删除 gpg2 --delete-keysgpg2 --delete-secret-keys

如果熟悉 scp 可以直接将 ~/.gnupg 目录复制到新机器中:

scp -rp ~/.gnupg name@server_ip:~/

reference


2017-10-20 github , git , gpg , linux

升级 Spring MVC 3.2.x 到 4.x 注意事项

把 Spring 版本从 3.2.x 升级到了4.x ,这里记录一下。

新特性

Java 8 Support, 从 4.0 开始支持 Java 8,可以使用 lambda 表达式,等等 Java 8 的特性

Groovy DSL

新增 @RestController 注解,这样就不需要每个方法都使用 @ResponseBody 了。

更多内容可以查看: https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#spring-whats-new

注意事项

添加依赖

加入spring-context-support,以前3的版本不用加,但是4要加上,否则就会报 ClassNotFoundException,

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.3.12.RELEASE</version>
</dependency>

替换 Spring MVC jackson 依赖

更换Spring jackson依赖,Spring MVC返回 json 的时候需要依赖jackson的jar包,以前是codehaus.jackson,现在换成了fasterxml.jackson 同时修改配置文件

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.7.0</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.7.0</version>
</dependency>

同时还要修改Spring的配置文件

<bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
             <ref bean="stringHttpMessageConverter" />  
            <bean
                class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            </bean>
        </list>
    </property>
</bean>

<bean id="stringHttpMessageConverter"
    class="org.springframework.http.converter.StringHttpMessageConverter">
    <property name="supportedMediaTypes">
        <list>
            <value>text/plain;charset=UTF-8</value>
        </list>
    </property>
</bean>

xsd 文件版本

更换springxsd文件的版本,直接从 3.0 升级到 4.0 即可

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

修改 quarz 版本

修改quarz版本,用2以上的版本,maven依赖如下

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.2</version>
</dependency>

2017-10-19 Spring , Java , Web

Linux 安装 nodejs

nodejs 安装其实非常简单,大部分情况下 Debian/Ubuntu 下只要使用包管理直接安装

sudo apt-get install nodejs
sudo apt-get install npm

即可。

脚本安装

可是今天网络环境太差,不是 npm package not found 就是 update 半天不动。

官网 提供的安装方式

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

也是网络环境无法安装

二进制安装

所以使用 二进制 安装

在官网 https://nodejs.org/en/download/ 找到编译好的二进制文件

然后解压到 /usr/local 目录下

然后配置 vim ~/.zshrc

export NODE_HOME=/usr/local/node-v6.11.4-linux-x64/
export PATH=$NODE_HOME/bin:$PATH

使用命令检查

node -v
npm -v

输出即可。

reference


2017-10-18 linux , nodejs , npm , js , javascript

使用 mutt 在 Bash 中发送邮件及附件

在编写定时备份脚本时遇到一个需求,就是在 Bash 脚本中发送带附件的邮件。于是找到了 mutt。

Mutt 是一个命令行的邮件客户端,Mutt 能够轻松地在命令行发送和读取邮件。 Mutt 支持 POP 和 IMAP 协议。 尽管 Mutt 是基于命令的,但也同样有一个友好的界面。

如果不使用界面,使用 Mutt 命令发邮件也非常方便,只需要一条命令即可发送或者批量发送邮件。

功能说明

E-mail 管理程序。

语法

mutt [-hnpRvxz][-a 文件][-b 地址][-c 地址][-f 邮件文件][-F 配置文件][-H 邮件草稿][-i 文件][-m 类型][-s 主题] 邮件地址

补充说明:mutt 是一个文字模式的邮件管理程序,提供了全屏幕的操作界面。

参数:

  • -a 文件 在邮件中加上附加文件。
  • -b 地址 指定密件副本的收信人地址。
  • -c 地址 指定副本的收信人地址。
  • -f 邮件文件 指定要载入的邮件文件。
  • -F 配置文件 指定 mutt 程序的设置文件,而不读取预设的.muttrc 文件。
  • -h 显示帮助。
  • -H 邮件草稿 将指定的邮件草稿送出。
  • -i 文件 将指定文件插入邮件内文中。
  • -m 类型 指定预设的邮件信箱类型。
  • -n 不要去读取程序培植文件 (/etc/Muttrc)。
  • -p 在 mutt 中编辑完邮件后,而不想将邮件立即送出,可将该邮件暂缓寄出。
  • -R 以只读的方式开启邮件文件。
  • -s 主题 指定邮件的主题。
  • -v 显示 mutt 的版本信息以及当初编译此文件时所给予的参数。
  • -x 模拟 mailx 的编辑方式。
  • -z 与 -f 参数一并使用时,若邮件文件中没有邮件即不启动 mutt。

安装方法

Debian/Ubuntu/Linux Mint 安装

sudo apt-get install -y mutt

使用方法

发送一封简单的邮件(可能会被主流邮箱认为垃圾邮件,垃圾箱查看一下)

echo "Email body" | mutt -s "Email Title" root@einverne.info

进入命令行交互界面之后使用如下快捷键操作

  • 使用 t 改变接受者邮件地址
  • 使用 c 改变 Cc 地址
  • 使用 a 来增加附件
  • 使用 q 退出
  • 使用 y 来发送邮件

发送带附件的邮件

echo "body" | mutt -s "mysql backup" root@einverne.info -a /mysql.tar.gz

读取文本中的信息作为内容

mutt -s "Test" xxxx@qq.com

添加多个附件

echo "body" | mutt -s "web backup" root@einverne.info -a /mysql.tar.gz -a /web.tar.gz

抄送和密送

echo "body" | mutt -s "title" -c cc@gmail.com -b bcc@gmail.com root@einverne.info
  • 使用 -c 来抄送
  • 使用 -b 来添加密送
  • 使用 -s 来添加标题
  • 使用 -a 来添加附件

设置发件人

编辑配置文件

vi /etc/Muttrc

添加如下内容,防止被作为垃圾邮件

set from="mutt@einverne.info"
set use_from=yes
set envelope_from="yes"
set realname="Ein Verne"

mutt@einverne.info 为发信地址

mutt 发送邮件略慢,需要等待一分钟或者更长才能发送成功,作为备份工具好好利用。

reference


2017-10-17 linux , email , mutt

Podcast 频道推荐

Podcast 作为一种特殊的借助声音传播的媒体,有着特定的适用场景和范围。对于我来说每当我需要放空我自己,而又需要使用眼睛和手的时候,比如长时间走路,开车,再比如乘坐地铁等等情况下都会不自觉的打开一集播客。对于固定时间的上下班时间会听固定时长差不多在 1h 左右的内容,而其他时刻根据不同的时长可能会有短到 10 分钟,或者长 30 分钟的内容。

拿播客跟传统电台广播相比,播客的制作可能会更加精良,主题更加集中,信息密度更大一些,大部分往往是针对某一个话题进行介绍或者讨论。

推荐使用通用性客户端订阅收听,比如 Google Podcasts,或者 Pocket Casts 等等,后文有整理。

每期必听

反派影评

反派影评:个人看电影比较多,从偶然听到一期“观影风向标”开始就一直追随者波米到了“反派影评”,这些年陆陆续续也听过不少影评类节目,但只有反派让我一直坚持到现在仍然每期必听。如果你是一个观影爱好者,那就一定不能错过这一档节目。反派影评在 Podcast 上只更新长节目,短节目还是要上微信公众号的。

  • 主题内容:每期主题一部电影,根据这部电影展开,从导演到演员等等
  • 时长:1h 以上
  • 更新周期:每周,但时间不固定

Self-Hosted

Self-Hosted 是一个关于如何自建各种服务,将自己的数字生活以及产生的数据自我管理的播客。

Talk Python to me (by Michael Kennedy)

这是一个和 Python 相关的播客,但是又不止于 Python,还包括 Data Science,AI,Web development 等等话题。

  • 官网:https://talkpython.fm/
  • 主题内容:Python 相关
  • 时长: 1h 左右
  • 更新周期:大致为一周

This American Life

This American Life is an American weekly hour-long radio program produced in collaboration with Chicago Public Media and hosted by Ira Glass. It is broadcast on numerous public radio stations in the United States and internationally, and is also available as a free weekly podcast.

  • 主题内容:This American Life
  • 时长: over 1 hour
  • 更新周期:大致为一周

Talk to me in Korean

学习基础韩国语的节目

  • 主题内容:韩语基础会话
  • 时长: less than 10min
  • 更新周期:大致为一周

牛津人文通识解读

从传统意义上这应该算是讲座了,因为《[[通往奴役之路]]》而在 YouTube 上得知这一个主题的演讲,所以下载之后转成音频在路上听了。演讲者是西北政法大学的副教授谌洪果,因为一些缘故辞职了。所以我们才能在 YouTube 上看到这一个系列的讲座,主讲的材料是基于《牛津人文通识》这样一套书籍,这一系列的书大多都是哲学类,或者哲学家相关的书籍,当然也有比如现代日本,美国大法官之类。这一个系列的讲座每一期围绕一本书进行一段分享,YouTube 上的内容不全,不过也陆陆续续听了 24 期,可以说每一期都非常值得听,现在依然记忆深刻的有,哈耶克的,美国最高法院,现代日本等等话题。

  • 主题内容:围绕牛津人文通识读本每期分享一期
  • 时长:1h-2h
  • 更新周期:不固定

Acquired

Acquired 是一个关注科技圈成功的收购和上市的节目,两位主持人 David 和 Ben 在投资界都有一定的经验 1, 能够听出来每一期节目都有非常充足的材料。有的时候他们也会分析一些国内的成功投资经验,比如 Tencent,Xiaomi,Alibaba 等等,也有一些非常热门的话题比如 Tesla,GitHub etc。

  • 官网:https://www.acquired.fm/
  • 主题内容:Exploring, Analyzing, and Grading Technology Acquisitions and IPOs
  • 时长:2h 左右
  • 更新周期:Season 季播,更新时周更

内核恐慌

听“两个中老年人程序员” 聊天。

  • 主题内容:程序,Mac,设计,字体,软件包等等
  • 时长:100 分钟以上
  • 更新周期:节目更新时间不固定

疯投圈

内核恐慌主持人 Rio 的另一档节目,年初刚开始听,果然质量还是不错的

  • 主题内容:投资,科技,消费,各行各业
  • 时长:60 分钟以上
  • 更新周期:节目更新时间不固定,一般月更

decoder

这是一档由 The Verge 推出的播客节目,听的第一期是因为想要了解更多关于 Airbnb 的内容,于是搜到了创始人 Brain Chesky 的访谈,发现这档节目不错

  • 主题内容:访谈,创业
  • 时长:60 分钟以上
  • 更新周期:周更

故事 FM

听不同人讲自己的故事。

  • 主题内容:不定
  • 时长:小于 30 min
  • 更新周期:每 3 天左右

日本自由行

青岛刘伟品质旅游主播的一档节目,主播是一位从事多年日本旅游工作的导游,从日本文化,历史,饮食,等等方面对日本做出一些介绍。当时就是随心所听,节目不长,声音录制设备也不是很好,但是内容短小精湛非常不错,在主播的推荐下陆陆续续接触了日本文化,甚至看了《日本论》《静观日本》等等书籍。

主播本人是一位职业导游,从 90 十年代开始从事中日导游,翻译工作,给国人定制深度旅游,也接待日方游客。节目内容重在文化,历史,从历史文化中了解日本人的礼仪,美学等等方面。

  • 主题内容:日本文化,旅游,自由行
  • 时长:30 分钟左右
  • 更新周期:前期节目不固定,后面固定为每周三更新

非每期必听但值得一提

忽左忽右

主题不固定,主要在于媒体,投资,互联网等等

  • 主题内容:不固定
  • 时长:30 分钟到 1 小时不定
  • 更新周期:不固定

静说日本 徐静波

或许直接去看讲述日本的书,要比直接听这个要好很多。个人不是非常喜欢这个频道。

  • 主题内容:日本
  • 时长:20 分钟以下
  • 更新周期:大概每周

百靈果 NEWS

这是一档台湾人做的双语国际新闻平台,当然听到后期就会发现主播们打着双语的旗号,其实更多的是在“聊天”,或者用他们自己的话说,就是“讲干话”。当然继续收听他们的节目主要是主播二人非常有趣。

国际新闻,双语,读书,闲聊,台湾

  • 主题内容:不固定
  • 时长:30 分钟到 1 小时不定
  • 更新周期:不固定

陌声人

每一期会分享一本图书

一席

朋友推荐,听了多抓鱼创始人的一集,确实不错,可以选择自己喜欢的话题和主题来听。通常情况下一集大概半个小时左右,会邀请以为专业人士就某一个话题进行演讲,看成是国内复刻版的 TED 吧。

  • 主题内容:
  • 时长:
  • 更新周期:

Breaking into Board Games

看名字就知道是和桌游相关的内容了

  • 主题内容:
  • 时长:
  • 更新周期:

翻转电台

一档和哲学,政治,经济,平民文化相关的电台

  • 主题内容:哲学、政治、经济、平民文化
  • 时长:30min~1h 不等
  • 更新周期:每周

InSession Film Podcast

一档英语影评节目

  • 主题内容:电影,演员,导演
  • 时长:1h 以上不等
  • 更新周期:Every 2 or 3 days.

政见合集

时政

选 美

美国政治

欧罗万象

NPR Up first

综合新闻

The Daily

纽约时报的 The Daily 专题报道

The Dropout

ABC The Dropout 听深度报道

欧洲政局变化

Planet Money

这档节目来自 NPR,绝对的明星节目。每期不到 30 分钟,把抽象的经济理论和政治决议与日常生活的种种现象结合,或者通过一个普通的生活事例分析出里面蕴含的经济学道理。听这档节目会上瘾。

曾经听过但个人不是很推荐

每个人都个人的喜好,网上很多 list 也不都是我最喜欢的博客,我觉得能够找到方法找到自己喜欢的某一类播客就是很好的,授人以鱼不如授人以渔,就是这样,但是这些我听过,并不是非常喜欢的播客我也列出来,喜不喜欢可以自行判断。

  • 代码时间
  • 电影不无聊
  • 闲侃日本
  • 新闻酸菜馆

Podcast 客户端推荐

早之前在 Android 的时候买过 Pocket Cast 可是竟然发现这家每个平台都要收费,不管是 Web ,还是 Android/iOS 客户端,每一个都是单独收费,尽管能够同步订阅列表,但后来转用 iOS 也就放弃了这个客户端,我用过的几个还不错的

  • Podcasts 苹果自身的客户端,虽然设计和使用都不是那么美观和人性化,但只要订阅了就会默默在 wifi 下帮你下载好,不用每一次上路了才想起来
  • Castbox,一款新出的客户端,客户端全免费,甚至网页版还提供博客平台的托管,虽然国内使用速度略慢,但是是我用过的里面体验比较好的了

至于其他人推荐的 Castro, Overcast 如果不缺钱的话买就行了。个人觉得重要的是内容,还有同步的功能,我希望我订阅的内容跟着账号走,而不是跟着设备走。其他国内的 app 比如 喜马拉雅,蜻蜓,荔枝 FM, 听伴 就凭着个人喜好选择即可。

至于为什么不推荐国内的这些 FM,是因为本来 Podcast 是一个公开分享的渠道,发布到 Podcast 上的内容可以被全世界的人访问到,而国内的 FM 都是闭门造车,封闭自己的用户,限制用户只能在他们的平台上传,听众也只有他们平台的账号才能收听,所有的内容就像是自家花园,外人不得入内。而放到 iTunes 的 Podcast 就像是放到了博物馆,全世界的人只要觉得有用就都能够收听到。而且封闭的环境导致审查异常严格,甚至聊电影都能碰到审查,同样也就导致了低智化内容泛滥,内容越没有思考越能得到平台的推荐,自此循环往复,推荐榜单就几乎没有能听的内容了。而在 Podcast 中反而一些很小众的 Channel 内容质量异常高,在某一个专业领域分享的知识,内容足够填满整个频道。

Podcast Hosting

其他站点

一个关于博客统计信息的站点

  • https://chartable.com/
  • https://github.com/guipdutra/awesome-geek-podcasts#in-chinese
  • https://wanqu.co/b/57/2017-03-03-podcasts.html

reference


2017-10-17 podcast , audio , castbox , pocket-cast , google-podcasts

电子书

最近文章

  • 如何进行有效的讨论 论 Clubhouse 这两天 Clubhouse 非常火热,又使得声音这一件事情被放到了台前,但听了多个 Room,并没有收获太多,反而是相对较大的「杂音」影响了收听,并且大部分的观点并没有让人眼前一亮的感觉。
  • 我的笔记法(借助 Zettelkasten 和 Obsidian) 在上次总结了2020读书笔记 之后,Tai 问我如何通过 Zettelkasten 和 Obsidian 来实践我的笔记。这里就也正好总结一下我自己的方法,希望可以在分享过程,或者和大家的讨论中来获取更多有效率方法。
  • 迟到的「给编程初学者的一封信」 这些天翻箱倒柜,翻出来一些大学时候的文档,其中一篇是当时上外教课时打印给我们的材料,虽然可以看得到当时也在上面做过笔记,但现在已经完全不记得有这样一份文档的存在了。但回过头再看文档的内容,每一句话都是非常珍贵的建议,是一份那个时期完全需要读一下的材料,但当时却并没有好好珍惜。这份文档的名字叫做「An open letter to those who want to start programming」,如果记得没错的话这份文档交到我手上的时候,应该就是我刚去学习如何编程的时候。如果当时就能够理解这一份文档内容的话,这些年来我肯定能少走不少的弯路。
  • 2020 读书记录 2020 年注定是会在历史上留下不平凡的一年,年初的疫情到年底问题依然还在,而且在不确定疫苗的情况,在加上英国的病毒变异情况,不清楚到什么时候才是结束。再回头看今年的大事小事,从年初的李文亮事件,到年末的蛋壳,以及阿里被禁止上A股,有些事情发生地太突然,来不及思考,但只有思考,不仅是在事前的还是事后的思考都有其价值。
  • 图片管理工具 Eagle 远在移动互联网还没有那么发达的今天,Google 曾经收购过一家图片管理与分享的网站叫做 Picasa,Picasa 同时提供了一个跨平台的照片管理工具 Picasa Desktop,用这个工具不仅可以非常方便的管理本地的图片文件,也可以非常方便的分享到 Picasa Web 上,然而随着移动互联网的到来,以及 Google 的转型,Picasa 的服务在 Google 变得没有那么重要,随即在 2016 年停止了服务,我的图片管理也被迫迁移到了 Google Photos。然而一切都开始变得不方便,Google Photos 内自动备份的照片,相册开始无法管理,并且 Google 停止了桌面版的开发,同样使得在桌面上管理图片变得困难,这些年来尝试了 Lightroom,TagSpaces 等等工具,都没有找到特别舒心的。