firewalld基本命令

1、运行、停止、禁用firewalld

启动:# systemctl start  firewalld

查看状态:# systemctl status firewalld 或者 firewall-cmd –state

停止:# systemctl disable firewalld

禁用:# systemctl stop firewalld

 

查看firewall是否运行,下面两个命令都可以

systemctl status firewalld.service
firewall-cmd --state

查看default zone和active zone

我们还没有做任何配置,default zone和active zone都应该是public

firewall-cmd --get-default-zone
firewall-cmd --get-active-zones

查看当前开了哪些端口

其实一个服务对应一个端口,每个服务对应/usr/lib/firewalld/services下面一个xml文件。

firewall-cmd --list-services

查看还有哪些服务可以打开

firewall-cmd --get-services

查看所有打开的端口:

firewall-cmd --zone=public --list-ports

更新防火墙规则:

firewall-cmd --reload

添加一个服务到firewalld

firewall-cmd --add-service=http //http换成想要开放的service

这样添加的service当前立刻生效,但系统下次启动就失效,可以测试使用。要永久开发一个service,加上 –permanent

firewall-cmd --permanent --add-service=http

如果要添加的端口并没有服务对应

就要新建一个服务,在/usr/lib/firewalld/services,随便拷贝一个xml文件到一个新名字,比如myservice.xml,把里面的

<?xml version="1.0" encoding="utf-8"?>

<service>
<short>Transmission-client</short>
<description>Transmission is a lightweight GTK+ BitTorrent client.</description>
<port protocol="tcp" port="51413"/>
</service>

short改为想要名字(这个名字只是为了人来阅读,没有实际影响。重要的是修改 protocol和port。修改完保存。我的经验是这是要重启firewalld服务,systemctl restart firewalld.service,否则可能提示找不到刚才新建的service。然后把新建的service添加到
firewalld

firewall-cmd --permanent --add-service=myservice

重启firewalld 生效

5分钟理解Centos7防火墙firewalld    http://www.cnblogs.com/stevenzeng/p/5152324.html

————————————————————————————————————-

1、firewalld的基本使用
启动: systemctl start firewalld
查看状态: systemctl status firewalld
停止: systemctl disable firewalld
禁用: systemctl stop firewalld
2.systemctl是CentOS7的服务管理工具中主要的工具,它融合之前service和chkconfig的功能于一体。

启动一个服务:systemctl start firewalld.service
关闭一个服务:systemctl stop firewalld.service
重启一个服务:systemctl restart firewalld.service
显示一个服务的状态:systemctl status firewalld.service
在开机时启用一个服务:systemctl enable firewalld.service
在开机时禁用一个服务:systemctl disable firewalld.service
查看服务是否开机启动:systemctl is-enabled firewalld.service
查看已启动的服务列表:systemctl list-unit-files|grep enabled
查看启动失败的服务列表:systemctl –failed

3.配置firewalld-cmd

查看版本: firewall-cmd –version
查看帮助: firewall-cmd –help
显示状态: firewall-cmd –state
查看所有打开的端口: firewall-cmd –zone=public –list-ports
更新防火墙规则: firewall-cmd –reload
查看区域信息:  firewall-cmd –get-active-zones
查看指定接口所属区域: firewall-cmd –get-zone-of-interface=eth0
拒绝所有包:firewall-cmd –panic-on
取消拒绝状态: firewall-cmd –panic-off
查看是否拒绝: firewall-cmd –query-panic
那怎么开启一个端口呢
添加
firewall-cmd --zone=public --add-port=80/tcp --permanent    (--permanent永久生效,没有此参数重启后失效)
重新载入
firewall-cmd --reload
查看
firewall-cmd --zone= public --query-port=80/tcp
删除
firewall-cmd --zone= public --remove-port=80/tcp --permanent

 

如何使youtube iframe嵌入的视频自适应 (100%宽度)

一般我们用这样的方式嵌入youtube视频:

<iframe width="560" height="315" src="//www.youtube.com/embed/yCOY82UdFrw" 
frameborder="0" allowfullscreen></iframe>

如果我们能将宽度的数值设置为 100% 会更加方便,但由于高度仍需要指定,因此并不可行,我们需要像这样把它包在一个container里:请注意类名,并且移除宽和高度属性。

<div class="container">
<iframe src="//www.youtube.com/embed/yCOY82UdFrw" 
frameborder="0" allowfullscreen class="video"></iframe>
</div>

使用以下css样式:

.container {
    position: relative;
    width: 100%;
    height: 0;
    padding-bottom: 56.25%;
}
.video {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

 

原理: container元素赋值了一个0值的高度和一个百分比的 bottom padding, 这个百分比的bottom padding 百分比是和容器宽度的百分比

,这就得到了一个固定的宽比率。但是为了让这个iframe显示在这个0高度的container里面,你需要设置container定位为relative,并将div里面的iframe的定位设置成absolute.

另一种方式是使用媒体查询。
https://www.h3xed.com/web-development/how-to-make-a-responsive-100-width-youtube-iframe-embed

 

PHP The Right Way

目前网络上充斥着大量的过时资讯,让 PHP 新手误入歧途,并且传播着错误的实践以及不安全的代码。PHP 之道 收集了现有的 PHP 最佳实践、编码规范和权威学习指南,方便 PHP 开发者阅读和查找。

使用 PHP 沒有规范化的方式。本网站主要是向 PHP 新手介绍一些他们没有发现或者是太晚发现的主题, 或是经验丰富的专业人士已经实践已久的做法提供一些新想法。本网站也不会告诉您应该使用什么样的工具,而是提供多种选择的建议,并尽可能地说明方法及用法上的差异。

当有更多有用的资讯以及范例时,此文件会随着相关技术的发展而持续更新。

Zend Opcache Error

0x0000200000000000

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Zend OPcache" /> 
  <EventID Qualifiers="0">2</EventID> 
  <Level>2</Level> 
  <Task>0</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2017-04-25T05:31:32.000000000Z" /> 
  <EventRecordID>234361</EventRecordID> 
  <Channel>Application</Channel> 
  <Computer>ASV51</Computer> 
  <Security /> 
  </System>
- <EventData>
  <Data>Unable to open base address file</Data> 
  <Data>The system cannot find the file specified.</Data> 
  </EventData>
  </Event>
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Zend OPcache" /> 
  <EventID Qualifiers="0">2</EventID> 
  <Level>2</Level> 
  <Task>0</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2017-04-25T05:31:32.000000000Z" /> 
  <EventRecordID>234361</EventRecordID> 
  <Channel>Application</Channel> 
  <Computer>ASV51</Computer> 
  <Security /> 
  </System>
- <EventData>
  <Data>Unable to open base address file</Data> 
  <Data>The system cannot find the file specified.</Data> 
  </EventData>
  </Event>

Centos7 安装Shadowsocks-libev

可以使用源码编译或者从yum repo安装,这里使用repo。

  1. 从 Fedora Copr 下载repo文件放到 /etc/yum.repos.d/ 目录下,使用root执行
    yum update
    yum install shadowsocks-libev
    

     

  2. 安装完成编辑文件 /etc/shadowsocks-libev/config.json ,加入以下内容:
    {
        "server":"0.0.0.0",
        "server_port":8888,
        "local_port":1080,
        "password":"你的密码",
        "timeout":300,
        "method":"aes-256-cfb"
    }

    其中server为你的服务器IP,默认是127.0.0.1 , 只在本地监听,不允许远程连接,设置为0.0.0.0时在服务器全部IP监听。server_port为服务器监听的端口,这里是8888。

  3. 运行服务并设置开机启动:
    systemctl start shadowsocks-server.service
    systemctl enable shadowsocks-server.service

     

  4. 防火墙开放相关端口:
    firewall-cmd --permanent --add-port=8888/tcp
    firewall-cmd --reload

     

参考:https://github.com/shadowsocks/shadowsocks-libev

 

[转] redis命令总结

1、连接操作相关的命令

  • quit:关闭连接(connection)
  • auth:简单密码认证

2、对value操作的命令

  • exists(key):确认一个key是否存在
  • del(key):删除一个key
  • type(key):返回值的类型
  • keys(pattern):返回满足给定pattern的所有key
  • randomkey:随机返回key空间的一个key
  • rename(oldname, newname):将key由oldname重命名为newname,若newname存在则删除newname表示的key
  • dbsize:返回当前数据库中key的数目
  • expire:设定一个key的活动时间(s)
  • ttl:获得一个key的活动时间
  • select(index):按索引查询
  • move(key, dbindex):将当前数据库中的key转移到有dbindex索引的数据库
  • flushdb:删除当前选择数据库中的所有key
  • flushall:删除所有数据库中的所有key

3、对String操作的命令

  • set(key, value):给数据库中名称为key的string赋予值value
  • get(key):返回数据库中名称为key的string的value
  • getset(key, value):给名称为key的string赋予上一次的value
  • mget(key1, key2,…, key N):返回库中多个string(它们的名称为key1,key2…)的value
  • setnx(key, value):如果不存在名称为key的string,则向库中添加string,名称为key,值为value
  • setex(key, time, value):向库中添加string(名称为key,值为value)同时,设定过期时间time
  • mset(key1, value1, key2, value2,…key N, value N):同时给多个string赋值,名称为key i的string赋值value i
  • msetnx(key1, value1, key2, value2,…key N, value N):如果所有名称为key i的string都不存在,则向库中添加string,名称key i赋值为value i
  • incr(key):名称为key的string增1操作
  • incrby(key, integer):名称为key的string增加integer
  • decr(key):名称为key的string减1操作
  • decrby(key, integer):名称为key的string减少integer
  • append(key, value):名称为key的string的值附加value
  • substr(key, start, end):返回名称为key的string的value的子串

4、对List操作的命令

  • rpush(key, value):在名称为key的list尾添加一个值为value的元素
  • lpush(key, value):在名称为key的list头添加一个值为value的 元素
  • llen(key):返回名称为key的list的长度
  • lrange(key, start, end):返回名称为key的list中start至end之间的元素(下标从0开始,下同)
  • ltrim(key, start, end):截取名称为key的list,保留start至end之间的元素
  • lindex(key, index):返回名称为key的list中index位置的元素
  • lset(key, index, value):给名称为key的list中index位置的元素赋值为value
  • lrem(key, count, value):删除count个名称为key的list中值为value的元素。count为0,删除所有值为value的元素,count>0从头至尾删除count个值为value的元素,count<0从尾到头删除|count|个值为value的元素。 lpop(key):返回并删除名称为key的list中的首元素 rpop(key):返回并删除名称为key的list中的尾元素 blpop(key1, key2,… key N, timeout):lpop命令的block版本。即当timeout为0时,若遇到名称为key i的list不存在或该list为空,则命令结束。如果timeout>0,则遇到上述情况时,等待timeout秒,如果问题没有解决,则对keyi+1开始的list执行pop操作。
  • brpop(key1, key2,… key N, timeout):rpop的block版本。参考上一命令。
  • rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部

5、对Set操作的命令

  • sadd(key, member):向名称为key的set中添加元素member
  • srem(key, member) :删除名称为key的set中的元素member
  • spop(key) :随机返回并删除名称为key的set中一个元素
  • smove(srckey, dstkey, member) :将member元素从名称为srckey的集合移到名称为dstkey的集合
  • scard(key) :返回名称为key的set的基数
  • sismember(key, member) :测试member是否是名称为key的set的元素
  • sinter(key1, key2,…key N) :求交集
  • sinterstore(dstkey, key1, key2,…key N) :求交集并将交集保存到dstkey的集合
  • sunion(key1, key2,…key N) :求并集
  • sunionstore(dstkey, key1, key2,…key N) :求并集并将并集保存到dstkey的集合
  • sdiff(key1, key2,…key N) :求差集
  • sdiffstore(dstkey, key1, key2,…key N) :求差集并将差集保存到dstkey的集合
  • smembers(key) :返回名称为key的set的所有元素
  • srandmember(key) :随机返回名称为key的set的一个元素

6、对zset(sorted set)操作的命令

  • zadd(key, score, member):向名称为key的zset中添加元素member,score用于排序。如果该元素已经存在,则根据score更新该元素的顺序。
  • zrem(key, member) :删除名称为key的zset中的元素member
  • zincrby(key, increment, member) :如果在名称为key的zset中已经存在元素member,则该元素的score增加increment;否则向集合中添加该元素,其score的值为increment
  • zrank(key, member) :返回名称为key的zset(元素已按score从小到大排序)中member元素的rank(即index,从0开始),若没有member元素,返回“nil”
  • zrevrank(key, member) :返回名称为key的zset(元素已按score从大到小排序)中member元素的rank(即index,从0开始),若没有member元素,返回“nil”
  • zrange(key, start, end):返回名称为key的zset(元素已按score从小到大排序)中的index从start到end的所有元素
  • zrevrange(key, start, end):返回名称为key的zset(元素已按score从大到小排序)中的index从start到end的所有元素
  • zrangebyscore(key, min, max):返回名称为key的zset中score >= min且score <= max的所有元素 zcard(key):返回名称为key的zset的基数 zscore(key, element):返回名称为key的zset中元素element的score zremrangebyrank(key, min, max):删除名称为key的zset中rank >= min且rank <= max的所有元素 zremrangebyscore(key, min, max) :删除名称为key的zset中score >= min且score <= max的所有元素
  • zunionstore / zinterstore(dstkeyN, key1,…,keyN, WEIGHTS w1,…wN, AGGREGATE SUM|MIN|MAX):对N个zset求并集和交集,并将最后的集合保存在dstkeyN中。对于集合中每一个元素的score,在进行AGGREGATE运算前,都要乘以对于的WEIGHT参数。如果没有提供WEIGHT,默认为1。默认的AGGREGATE是SUM,即结果集合中元素的score是所有集合对应元素进行SUM运算的值,而MIN和MAX是指,结果集合中元素的score是所有集合对应元素中最小值和最大值。

7、对Hash操作的命令

  • hset(key, field, value):向名称为key的hash中添加元素field<—>value
  • hget(key, field):返回名称为key的hash中field对应的value
  • hmget(key, field1, …,field N):返回名称为key的hash中field i对应的value
  • hmset(key, field1, value1,…,field N, value N):向名称为key的hash中添加元素field i<—>value i
  • hincrby(key, field, integer):将名称为key的hash中field的value增加integer
  • hexists(key, field):名称为key的hash中是否存在键为field的域
  • hdel(key, field):删除名称为key的hash中键为field的域
  • hlen(key):返回名称为key的hash中元素个数
  • hkeys(key):返回名称为key的hash中所有键
  • hvals(key):返回名称为key的hash中所有键对应的value
  • hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value

8、持久化

  • save:将数据同步保存到磁盘
  • bgsave:将数据异步保存到磁盘
  • lastsave:返回上次成功将数据保存到磁盘的Unix时戳
  • shundown:将数据同步保存到磁盘,然后关闭服务

9、远程服务控制

  • info:提供服务器的信息和统计
  • monitor:实时转储收到的请求
  • slaveof:改变复制策略设置
  • config:在运行时配置Redis服务器

Redis高级应用
1、安全性
设置客户端连接后进行任何操作指定前需要密码,一个外部用户可以再一秒钟进行150W次访问,具体操作密码修改设置redis.conf里面的requirepass属性给予密码,当然我这里给的是primos
之后如果想操作可以采用登陆的时候就授权使用:
sudo /opt/java/redis/bin/redis-cli -a primos
或者是进入以后auth primos然后就可以随意操作了

2、主从复制
做这个操作的时候我准备了两个虚拟机,ip分别是192.168.15.128和192.168.15.133
通过主从复制可以允许多个slave server拥有和master server相同的数据库副本
具体配置是在slave上面配置slave
slaveof 192.168.15.128 6379
masterauth primos
如果没有主从同步那么就检查一下是不是防火墙的问题,我用的是ufw,设置一下sudo ufw allow 6379就可以了
这个时候可以通过info查看具体的情况

3、事务处理
redis对事务的支持还比较简单,redis只能保证一个client发起的事务中的命令可以连续执行,而中间不会插入其他client的命令。当一个client在一个连接中发出multi命令时,这个连接会进入一个事务的上下文,连接后续命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令。
比如我下面的一个例子
set age 100
multi
set age 10
set age 20
exec
get age –这个内容就应该是20
multi
set age 20
set age 10
exec
get age –这个时候的内容就成了10,充分体现了一下按照队列顺序执行的方式
discard 取消所有事务,也就是事务回滚
不过在redis事务执行有个别错误的时候,事务不会回滚,会把不错误的内容执行,错误的内容直接放弃,目前最新的是2.6.7也有这个问题的
乐观锁
watch key如果没watch的key有改动那么outdate的事务是不能执行的

4、持久化机制
redis是一个支持持久化的内存数据库
snapshotting快照方式,默认的存储方式,默认写入dump.rdb的二进制文件中,可以配置redis在n秒内如果超过m个key被修改过就自动做快照
append-only file aof方式,使用aof时候redis会将每一次的函 数都追加到文件中,当redis重启时会重新执行文件中的保存的写命
令在内存中。
5、发布订阅消息 sbusribe publish操作,其实就类似linux下面的消息发布
6、虚拟内存的使用
可以配置vm功能,保存路径,最大内存上线,页面多少,页面大小,最大工作线程
临时修改ip地址ifconfig eth0 192.168.15.129

redis-cli参数
Usage: redis-cli [OPTIONS] [cmd [arg [arg …]]]
-h Server hostname (default: 127.0.0.1)
-p Server port (default: 6379)
-s Server socket (overrides hostname and port)
-a Password to use when connecting to the server
-r Execute specified command N times
-i When -r is used, waits seconds per command.
It is possible to specify sub-second times like -i 0.1
-n Database number
-x Read last argument from STDIN
-d Multi-bulk delimiter in for raw formatting (default: \n)
-c Enable cluster mode (follow -ASK and -MOVED redirections)
–raw Use raw formatting for replies (default when STDOUT is not a tty)
–latency Enter a special mode continuously sampling latency
–slave Simulate a slave showing commands received from the master
–pipe Transfer raw Redis protocol from stdin to server
–bigkeys Sample Redis keys looking for big keys
–eval Send an EVAL command using the Lua script at
–help Output this help and exit
–version Output version and exit

Examples:
cat /etc/passwd | redis-cli -x set mypasswd
redis-cli get mypasswd
redis-cli -r 100 lpush mylist x
redis-cli -r 100 -i 1 info | grep used_memory_human:
redis-cli –eval myscript.lua key1 key2 , arg1 arg2 arg3
(Note: when using –eval the comma separates KEYS[] from ARGV[] items)

常用命令:
1) 查看keys个数
keys * // 查看所有keys
keys prefix_* // 查看前缀为”prefix_”的所有keys

2) 清空数据库
flushdb // 清除当前数据库的所有keys
flushall // 清除所有数据库的所有keys

 

 

via https://maoxian.de/2015/08/1342.html

[转]利用WordPress自带的缓存功能加速自定义查询

WordPress有一套自己的缓存系统,其实不用任何插件,WordPress就可以缓存查询内容,和其他程序一样,WordPress缓存主要是缓存的MySQL查询数据,网站速度慢大部分原因是因为这个。缓存系统的实现无非是添加缓存,获取缓存,更新缓存等操作。WordPress的缓存系统为我们提供了方便的函数来实现缓存操作。

缓存的CRUD操作

添加缓存

在这里,$key就是缓存的键,$data就是缓存的值,$expire为过期时间,我们这里设置为不过期。

wp_cache_add($key, $data, $flag = '', $expire = 0)

删除缓存

需要清除缓存的时候,用这个函数把缓存删除掉,下次访问该数据的时候重新生成缓存。

wp_cache_delete($id, $flag = '')

获取缓存数据

这里是直接从缓存中获取到的数据,不用再查询数据库了,这是缓存加速的核心所在。

wp_cache_get($id, $flag = '')

替换缓存数据:

如果发表了文章,直接更新一下缓存,缓存的数据就是最新的了。

wp_cache_replace($key, $data, $flag = '', $expire = 0)

和wp super cache的区别

和wp super cache 不一样的是,WordPress内置的缓存系统不生成静态文件,而是把缓存以K-V的形式保存在数据库里面了,在存取上会快很多,如果我们配合使用了memcache或者redis缓存的插件,把缓存数据保存在内存中,缓存效率比wp super cache是要快很多的。

iTerm2 技巧

已经用 iTerm2 替换系统terminal有一段时间了,下面整理一下 iTerm2 使用的一些tips:

1.选中即复制

在iTerm2中,直接用鼠标选中某个单词或者一行命令,那么就已经被复制了。不需要在去按command+C命令了。

2.屏幕分隔

command+d:垂直分割;

command+shift+d:水平分割

切割后的窗口可用快捷键:command+[ 或command+] 切换。

3.快速唤出

这个同样是我很喜欢的功能,炫酷到无法阻挡。设置好系统热键之后,只要按快捷键,iTerm2就会从顶部以半透明的形式快速唤出,相当炫酷高效。个人因为经常使用iTerm2,所以设置了热键为:option+空格键。大家也可以根据自己的喜好设置快捷键。

使用快捷键快速唤出的效果。。。貌似是直接浮动在窗口上的,我截不了屏。。。大家尝试去感受下。

4.显示复制历史

使用快捷键shift+command+h,快速显示出我复制过的历史记录,你可以快速选择使用。

5.全屏切换

command+enter,可以快速实现全屏与正常窗口大小的切换,非常方便

 

6.一些比较有用的快捷键:

command+左/右箭头在多标签间切换

command+;查看历史/补全命令

快捷键

  • ⌘ + Click:可以打开文件,文件夹和链接
  • ⌘ + n:新建窗口
  • ⌘ + t:新建标签页
  • ⌘ + w:关闭当前页
  • ⌘ + 数字 ⌘ + 方向键:切换标签页
  • ⌥⌘ + 数字:切换窗口
  • ⌘ + enter:切换全屏
  • ⌘ + d:左右分屏
  • ⇧⌘ + d:上下分屏
  • ⌘ + ;:自动补全历史记录
  • ⇧⌘ + h:自动补全剪贴板历史
  • ⌥⌘ + e:查找所有来定位某个标签页
  • ⌘ + r ⌃ + l:清屏
  • ⌘ + /:显示光标位置
  • ⌥⌘ + b:历史回放
  • ⌘ + f:查找,然后用 tab⇧ + tab 可以向右和向左补全,补全之后的内容会被自动复制,
    还可以用 ⌥ + enter 将查找结果输入终端
  • 选中即复制,鼠标中键粘贴

很多快捷键都是通用的,和 Emace 等都是一样的

  • ⌃ + u:清空当前行
  • ⌃ + a:移动到行首
  • ⌃ + e:移动到行尾
  • ⌃ + f:向前移动
  • ⌃ + b:向后移动
  • ⌃ + p:上一条命令
  • ⌃ + n:下一条命令
  • ⌃ + r:搜索历史命令
  • ⌃ + y:召回最近用命令删除的文字
  • ⌃ + h:删除光标之前的字符
  • ⌃ + d:删除光标所指的字符
  • ⌃ + w:删除光标之前的单词
  • ⌃ + k:删除从光标到行尾的内容
  • ⌃ + t:交换光标和之前的字符

还有鼠标和触摸板控制
Preferences – Pointer

禁止 Crayon Syntax Highlighter 的前台渲染

Crayon Syntax Highlighter 是一个优秀的WordPress代码高亮插件,格式化的样式漂亮,完美集成在WordPress的后台编辑器功能上,本站也是使用该插件,唯一的缺点是内存开销有点大,特别是对小内存的VPS,动不动就引发502错误了。所以我决定放弃前台的渲染效果,使用本主题默认风格的代码高亮效果,本人初期加入的功能,虽然不及Crayon Syntax Highlighter 华丽,也满足需求了。

代码修改很简单,只要在 craypon_wp.class.php1280 行左右的地方加入return false 即可

// Only if WP is loaded
if (defined('ABSPATH')) {
    if (!is_admin()) {
        // Filters and Actions
        retrun false; // 加入此行,禁止前台语法高亮的渲染
        add_filter('init', 'CrayonWP::init');

 

 

为bash shell添加git分支名称提示

众所周知,zsh有一个非常好用的功能,进入git项目里,在终端可以看到git分支的名称提示:

zsh git分支提示

而在bash默认没有这个功能, 但是也是很简单,在网上找了一下,几行代码就实现了。非常简单。

1 在~/.bashrc文件里新增一个函数,用于获取git的分支信息

parse_git_branch() {
     git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}

2 将获取的git分支信息附加到终端提示符之后

#PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] ' # old bash shell prompt
PS1="\[\033[01;32m\]\u@\h\[\033[01;34m\] \w\[\033[33m\]\$(parse_git_branch)\[\033[00m\] "

完成后,执行一次~/.bashrc或者重新打开终端即可

source ~/.bashrc

bash git branch

参考:https://coderwall.com/p/fasnya/add-git-branch-name-to-bash-prompt

七牛云的免费SSL证书申请和用法

网站的SSL证书过期了,是去年在StartSSL签发的,现在他们家的名声不太好,已经不推荐使用他们的证书了,网上转了一圈,开始申请阿里云的免费证书,是Symantec 免费DV , 然后三天了还在审核中,
Snip20170318_150
我也是醉了,平时发垃圾短信推荐各种服务明明那么勤快的说。。。

然后看到论坛上有人推荐 七牛 的证书,就去申请了,登录之后在个人面板找到“证书管理”,
Snip20170318_151
点击进入证书管理页,点击”申请证书”
证书管理
然后填写域名和个人信息,可以看到是和阿里云一样的 “赛门铁克(Symantec) DV SSL证书”:

 证书类型

填完后会在证书列表看到订单号,像这样的,
订单列表

注意:目前七牛免费证书是单域名证书,即1个证书对应1个域名。不支持多域名和泛域名绑定,所以多个子域名就要多次申请了,但是申请根域名的证书对www子域也可用。也就是cellmean.com的证书可以用在www.cellmean.com上。

然后去配置DNS验证,我的域名使用DNSpod的服务,在域名解析页增加一条TXT记录。
如果是根域名证书,主机记录 请使用 “@” ,其他填 证书列表 下的TXTkey,(注:万网和DNSpod平台TXTkey不需要复制主域名部分),记录值填写TXT value 。比如说我申请的是 gg.cellmean.com 的证书,需要这样填写:
DNSpod记录
这样就进入了域名循环验证的阶段了,可以使用dig命令查看解析情况:
~ dig gg.cellmean.com txt

; <<>> DiG 9.8.3-P1 <<>> gg.cellmean.com txt
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15990
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;gg.cellmean.com.		IN	TXT

;; ANSWER SECTION:
gg.cellmean.com.	38	IN	TXT	"201703111219325rba89h2a0urq8d74vgh1l9hafkuzn1c6it5ohw298pit07xzc"

;; Query time: 637 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: Sat Mar 18 16:15:18 2017
;; MSG SIZE  rcvd: 110

稍等片刻,大概10分钟到半个小时,验证完成了。

验证完成
证书可以在七牛的cdn里指定使用,也可以放在自己的服务器使用。我当然是放在自己的服务器用的,所以我们需要把证书内容和私钥保存和设置到服务器上。那么怎么取得证书呢?七牛的文档没说,但是也很简单, 控制台找到CDN列表,新建加速域名,或者直接点击这个地址 ,在协议里选https,证书选刚才创建的,就看到证书内容和私钥的字符串了。
证书密钥
然后把证书内容保存到 gg.cellmean.com.crt ,把私钥保存到 gg.cellmean.com.key 。
然后在nginx 里设置如下:
server {
    listen 443 ssl;
    server_name gg.cellmean.com ;
    ssl_certificate /path/to/gg.cellmean.com.crt;
    ssl_certificate_key /path/to/gg.cellmean.com.key;
....

重启nginx ,新证书就生效了。比如 :https://gg.cellmean.com ,可以看到小绿锁和证书的信息了,哈哈。证书生效

PyQT5 在osx上设置icon的问题

最近在学习PyQT5,参考 http://www.cnblogs.com/archisama/p/5442071.html 的教程,教程翻译自:zetcode , 刚开始就遇到了一个奇怪问题,就是在设置应用的icon的时候,在osx 10.11.6系统,按照例程死活显示不出来图标。

例程是这样的:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

This example shows an icon
in the titlebar of the window.

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon


class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
    def initUI(self):
        
        self.setGeometry(300, 300, 300, 220)
        self.setWindowTitle('Icon')
        self.setWindowIcon(QIcon('web.png'))        
    
        self.show()
        
        
if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

Google搜索了一下,发现在 stackoverflow 也有人遇到同样的问题。如果按采用的答案也没有成功,但确实是要把这个方法放到Qapplication实例,然后再加上第二个哥们的回答,在 Qicon 里再调用一次Qpixmap ,并且传入一个ico格式的图片才能成功。完整代码如下:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import sys,os

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon,QPixmap


class Example(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.setGeometry(300, 300, 300, 220)
        self.setWindowTitle('Hello Icon')
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    path = os.path.join(os.path.dirname(sys.modules[__name__].__file__), 'good.ico')
    app.setWindowIcon(QIcon(QPixmap(path)))
    ex = Example()
    sys.exit(app.exec_())

这样就显示出来了。

Snip20170312_121

 

Mac OSX EI Capitan架设PyQt5开发环境

最近想学Python桌面编程,看上了PyQt5的跨平台性。文档和教程也很多,下面是比较有用的教程和example:

http://zetcode.com/gui/pyqt5/

https://pythonspot.com/en/pyqt5/

 

下面是在 Mac OSX EI Captian 上安装PyQt5环境的步骤, homebrew 慢成狗,我决定上手动档:

    1. 安装python3 (略)
    2. 安装Qt5 ,当前最新版本为5.8.0 ,下载地址:http://download.qt.io/official_releases/qt/5.8/5.8.0/ ,选择 qt-opensource-mac-x64-clang-5.8.0.dmg ,安装后默认位置是在当前用户家目录的Qt5.8.0文件夹 ,如我的安装目录:/Users/falcon/Qt5.8.0,然后把

      /Users/falcon/Qt5.8.0/5.8/clang_64/bin 加入 PATH 环境变量。

       

    3. 编译安装sip,下载地址 https://www.riverbankcomputing.com/software/sip/download ,当前为4.1.9。下载解压后,进入目录执行:

      python3 configure.py
      make
      sudo make install

      也可以使用 pip3 install sip 直接安装,参考:https://pypi.python.org/pypi/SIP/4.19.1
    4. 编译安装PyQt5, 下载地址:https://www.riverbankcomputing.com/software/pyqt/download5 解压后跟编译sip一样,在目录下执行:python3 configure.py
      make
      sudo make install

      安装时间略长。。。
    5. 准备就绪,写一个PyQt的应用测试吧。wordpress这个复制python太坑了,直接去掉了缩进,只能贴图了,我找个代码高亮的插件来格式化:
      Snip20170226_54

 

Snip20170226_53

Mac OS X El Capitan 关闭sip

Mac OS X El Capitan系统的升级,启用了更高的安全性保护机制:系统完整性保护System Integrity Protection (SIP)。简单来讲就是更加强制性的保护系统相关的文件夹。开发者不能直接操作相关的文件内容。

那么我们把它关闭就好了:

  1. 重启系统
  2. 按住 Command + R 进入 Recoverary 模式
  3. 点击 实用工具 > 终端
  4. 输入 csrutil disable
  5. 重启系统

 

震惊了:调用渣浪短网址服务(旧)生成短网址,小心掉坑

众所周知,新浪微博有一个短网址功能,会把你在微博发的原链接转成http://t.cn/XXOO的形式。开放了API,也就是这个:

http://open.weibo.com/wiki/2/short_url/shorten ,调用这玩意还居然要access_token ,我也是醉了,搜索了一下,找到一个旧版的接口,不需要access_token, 只要申请或者随便找一个appkey就能用了, 详细说明看这篇https://www.douban.com/note/249723561/ ,

对应的URL请求地址为:

xml:http://api.t.sina.com.cn/short_url/shorten.xml
json:http://api.t.sina.com.cn/short_url/shorten.json

请求方式:GET
请求参数:
  source:应用的appkey
  url_long:需要转换的长链接
举个例子:
xml:http://api.t.sina.com.cn/short_url/shorten.xml?source=3271760578&url_long=http://www.douban.com/note/249723561/
返回内容为:
<urls>
<url>
<url_short>http://t.cn/zWXySpZ</url_short>
<url_long>http://www.douban.com/note/249723561/</url_long>
<type>0</type>
</url>
</urls>

json:http://api.t.sina.com.cn/short_url/shorten.json?source=3271760578&url_long=http://www.douban.com/note/249723561/
返回内容为:
[{"url_short":"http://t.cn/zWXySpZ","url_long":http://www.douban.com/note/249723561/","type":0}]


测试了一下,服务仍然可用,但这个接口是有问题的,貌似是旧版api遗留下来的, 首先这个请求参数url_long的地址不必使用url_encode, 新版是需要的(而且也是必要的),经测试发现被 url_encode过的long_url只会返回”[]”,这导致当请求原链接带”&”时就不能正确识别,比如http://blog.cellmean.com?post_type=post&id=10086, 则发送:

“http://api.t.sina.com.cn/short_url/shorten.json?source=3271760578&url_long=http://blog.cellmean.com?post_type=post&id=10086”;

返回:

[
{
“url_short”: “http://t.cn/RiZMd85”,
“url_long”: “http://blog.cellmean.com?post_type=post”,
“type”: 0
}
]

这样”&id=10086″的部分会被吃掉,实际上返回的是”http://blog.cellmean.com?post_type=post”的短链接。如果要得到正确的结果,只能对”&”单独进行一次urlencode,替换成”%26″,或者转换成html实体”&amp;”;
即请求:

“http://api.t.sina.com.cn/short_url/shorten.json?source=3271760578&url_long=http://blog.cellmean.com?post_type=post%26id=10086”

返回值:

[{“url_short”:”http://t.cn/RiZqrtU”,”url_long”:”http://blog.cellmean.com?post_type=post&id=10086″,”type”:0}]

 

然后我简单封装了一下, 代码如下:

function sina_url_shorten( $url,$source='3271760578' ) {
    echo $request_url = "http://api.t.sina.com.cn/short_url/shorten.json?source=".$source .'&url_long='. str_replace("&","%26",$url);
    $data = file_get_contents($request_url);
    $array = json_decode($data,true);
    if( isset($array[0] )) {
        return $array[0]['url_short'];
    }else{
        return false;
    }

}

$long_url = 'http://blog.cellmean.com/book/%E5%8F%B2%E8%AE%B0/?cid=5689142fa8c4a4100065298&from=10086';
echo sina_url_shorten($long_url);


没有弄http的错误处理,密钥是网上找到的,可能会有调用频率限制,可以在这个页面申请一个 : http://open.weibo.com/connect 然而这个立即连接半天点不动。

最后说明:标题灵感源于“UC震惊部”:)

[转]wordpress文章URL重写规则和重写标签

wordpress是可以自定义文章的连接的,可是有些文章我们想通过文章的ID直接访问,而不是通过post_name去访问,比如自定义的分类里面的文章,比如我们有一篇文章的ID为4656,自定义分类为book,那么如何通过这样的“www.uedsc.com/book/4656.html”链接访问文章呢?

重写规则
如果熟悉了wordpress的重写规则,那么很简单:

add_action('generate_rewrite_rules', 'ashu_rewrite_rules' );
function ashu_rewrite_rules( $wp_rewrite ){
$new_rules = array(
'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',
'top'
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}

上面的重写规则中正则表达式:[0-9]即匹配数字,在主题的functions.php中添加上面的代码即可,如果你需要其它类型的URL重写规则,你可以自己编写上面的正则表达式。

然而我们从通过模板输出的链接,或者通过后台点击查看文章,发现链接还是:“www.uedsc.com/book/文章名”,在主题中添加下面的代码:

add_filter('post_type_link', 'ashu_book_link', 1, 3); //过滤器post_type_link即输出链接的时候用
function ashu_book_link( $link, $post = 0 ){
if ( $post->post_type == 'book' ){ //判断如果是book类型的文章
    return 'http://www.ashuwp.com/book/'.$post->ID .'html'; //返回一个正确的链接
 } else {
    return $link;
 }
}

 

即可输出正确的链接,然而教程到了这里,还没进入正题–重写标签。上面两个代码知识为了熟悉一下重写规则的使用。

重写标签
重写标签在wordpress后台-设置-固定连接里面用到的 %post_id% %post_name%之类的就是重写标签了,我们前面也说过,wordpress后台设置的“固定链接格式”是会保存到数据库中的 _options表中,重写标签的主要作用也就是用来建立一个“固定链接格式”

上面添加的段代码,完全可以用下面的一段代码来代替:

add_action('init', 'ashu_book_rewrite');
function ashu_book_rewrite() {
    global $wp_rewrite;
    $queryarg = 'post_type=book&p=';
    $wp_rewrite->add_rewrite_tag('%book_id%', '([^/]+)', $queryarg);
    //这里的%book_id%就是重写标签,第二个参数为匹配这个标签的正则表达式,第三个参数这个标签匹配的翻译规则
    $wp_rewrite->add_permastruct('book', '/book/%book_id%.html', false);
    //add_permastruct是往数据库中保存一个固定链接格式,第一个参数为名称
}

 

add_filter('post_type_link', 'ashu_book_permalink', 1, 3);
function ashu_book_permalink($post_link, $post = 0) {
    global $wp_rewrite;
    if ( $post->post_type == 'book' ){ //判断文章类型
    if ( is_wp_error( $post ) )
    return $post;
    $newlink = $wp_rewrite->get_extra_permastruct('book'); //获取前面保存的名为book的固定链接格式
    $newlink = str_replace("%post_id%", $post->ID, $newlink); //将格式里面的重写标签替换为文章ID
    $newlink = home_url(user_trailingslashit($newlink)); //完整的链接地址
    return $newlink; //返回
} else {
    return $post_link;
}
}

 
上面的代码中,输出连接就不用解释了。翻译:当访客访问地址“www.uedsc.com/book/4656.html”,这个地址刚好匹配了名 为“book”的固定连接格式,而这个格式里面的标签“%book_id%”是要翻译成“post_type=book&p=”的,所以翻译为 “www.uedsc.com/?post_type=book&p=4656”这样就能正确翻译了。所以上面的 add_rewrite_tag和add_permastruct两个函数组合的效果和使用函数添加重写的规。

使用FFmpeg合并多个视频

最近有一个需求,想把一堆mp4文件合并成一个大的文件,macOS下找了几个工具都不是很理想。后来我想起Linux下强大的视频工具FFmpeg,谷歌了几下,问题轻松解决了。

首先安装ffmpeg。

brew install ffmpeg

然后进入那堆mp4文件的目录。执行:

for f in ./*.mp4; do echo “file ‘$f'” >> mylist.txt; done

这样就生成了一个所有mp4文件的列表mylist.txt,可以在这个文件里手动调整一下视频的顺序,或者删除一些不需要的视频。

最后就轮到ffmpeg登场了:

ffmpeg -f concat -i mylist.txt -c copy myvideo.mp4

其中myvideo.mp4就是合并后的文件。如果出现类似提示:

[concat @ 0x7f97d9009000] Unsafe file name ‘./00M00S.mp4’
mylist.txt: Operation not permitted

可以在 concat 后面加上 -safe 0 参数,这样命令变成:

ffmpeg -f concat -safe 0  -i mylist.txt -c copy myvideo.mp4

合并瞬间完成,很简单吧。have fun !

 

如何实现 Windows 7/Vista 开机自动登录而不用输入密码

密码登录是系统保护用户信息的一种安全机制,但在某些场合,比如家里,每次登录都输入密码就显得有些多此一举了。

直接登录也许是更佳的选择。如何实现呢?一起来看看。

  1. Win”+“R”打开命令窗口,输入”control userpasswords2“(不包括引号),回车。
    a
    若有用户账户控制窗口跳出,请按“继续”。
    b
  2. 在出现的“用户帐户”设置窗口中,取消“要使用本机,用户必须输入用户名和密码”的选择,然后“应用”。在弹出的“自动登录”对话框中输入密码,确定。下次启动计算机时即可自动登录。
    c

对于之前设置过需要按“Ctrl+Alt+Del”登录的用户,还需要多走一步,对 Vista 系统的组策略参数稍稍修改一下。

  1. 在开始搜索框中,键入“gpedit.msc”命令,回车。
    d
  2. 进入系统的组策略编辑窗口;在左侧,用鼠标逐一展开“计算机配置”〉“Windows 设置”〉“安全设置”〉“本地策略”〉“安全选项”。
    e
  3. 在对应“安全选项”项的右侧窗口中,鼠标双击“交互式登录:无需按Ctrl+Alt+Del”组策略选项。然后在设置窗口中,点选“已启用”,按“确定”保存设置,退出编辑器。
    f