计算机编程 类目

学会编程我们能够和计算机沟通

浅谈 Shell 脚本配置文件格式

开发过程中为了减少 hardcode,不可避免的需要提供配置文件给用户定制。对于高级编程语言来说,因为有丰富的第三方库,可供选择的配置文件格式有很多,比如 xml、jsno、ini、yaml 等等。

key=value 文本格式配置

而对于 linux shell,基本上很难使用前面提到的各种格式。所以在 unix 系统上,很多 shell 脚本的配置文件都是纯粹的 key=value 文本格式,例如绝大多数的开机服务启动脚本、网络配置文件等。

例子 1:ntp 配置文件

$ cat /etc/sysconfig/ntpd
# Drop root to id 'ntp:ntp' by default.
OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid"

# Set to 'yes' to sync hw clock after successful ntpdate
SYNC_HWCLOCK=no

# Additional options for ntpdate
NTPDATE_OPTIONS=""

例子 2:网络配置文件

$ cat /etc/sysconfig/network
NETWORKING="yes"
HOSTNAME="xx.com"

而且,要注意得是,一般 key=value 的等号两边不应该有空格,因为大多数脚本都是直接 source 配置文件的(当然,也有部分脚本是会自己处理配置文件格式),使用起来很简单,基本上没有解析的操作:

$ cat /etc/init.d/network
if [ ! -f /etc/sysconfig/network ]; then
    exit 0
fi

. /etc/sysconfig/network

理所当然,这种格式无法满足更复杂的配置文件需求,比如 ini 格式的 section。那么,在 shell 中除了满世界去找一个解析库之外,能有什么方法可以实现呢?

扩展 key=value 文本格式配置

假设,我们管理着 n 个集群,每个集群配置项都是一样的,我们需要在 shell 脚本中,可以根据集群的名称来导入对应的配置。

查看全文

理解 IFS

Bash 里的 word splitting 是很基础的一个知识点,如果没有理解透彻,很多时候会犯下不少奇奇怪怪的错误(参见 Bash Pitfalls,或者本博客翻译 Bash Pitfalls: 编程易犯的错误(一))。

一个例子,现在我们现在要一次读入文件 onefile.txt 的内容并输出,假设文件的内容是这样的:

kodango -> ~/Workspace/coding/test
$ cat onefile.txt
hello world

当我们习惯性地使用 for 循环来解决这个问题时,你会发现输出的结果与预期大相径庭:

$ for i in $(<onefile .txt); do echo "$i"; done
hello
world

给我们的脑子也打开调试开关。首先 onefile.txt 的内容一次性地输出给 for 循环,我在中间用比较形象的 tag 来描述一个空白字符:

hello<blank>world<newline><blank><newline>

这个时候,word splitting 发生了,将以上字符串按照 IFS 分隔成 helloworld。IFS 是用来分隔命令中的每一个单词的,它可以有多个字符组成,每个字符都被视作分隔符。默认情况下,它的值为 <newline><tab><whitespace,这也是为什么默认都是按空格、回车等空白字符分隔的原因。

这样一来 hello 和 world 被分隔可以很好地解释,但是那又是为什么第二行的空行没有了呢?原来,当 IFS 包含空白字符时(比如回车、空格、制表符等),在任何需要分隔单词的场景下,位于字符串开头和结尾的空白字符会被删除,另外一点是,字符串中间的连续空白会被压缩成一个。

查看全文

Alfred workflow: 查询 IP 地址信息

今天给大家分享的 Alfred workflow,是用来查询 IP 地址信息,数据来源为淘宝 IP 地址库

淘宝 IP 地址库开放了查询 IP 的 API 接口,我们可以根据用户提供的 IP 地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家、省、市和运营商。根据官方的介绍,地址库中覆盖的 IP 地址数量以及准确度都很不错。

用法

在此之前,确认你的 Alfred 2 已经激活了 PowerPack 扩展功能。

然后从地址下载 Lookup IP Workflow,双击安装。

在 Alfred 框中输入关键字 lip, 参数可选,例如:

lip  # 查询本机的 IP 地址
lip 199.91.73.222 178.79.131.110  # 查询指定的多个 IP 地址
lip 199.91.73.222,178.79.131.110  # 查询指定的多个 IP 地址
lip 199.91.73.222178.79.131.110  # 查询指定的多个 IP 地址

从上可以看出,对参数格式的要并不高,只要参数中包含至少一个合法的 IP 地址即可。

示例

查询 IP: 42.120.194.11(taobao.com),42.120.158.67(aliyun.com)

alfred-lookup-ip

Alfred workflow: 快速切换 DNS 服务器设置

这是一个 Alfred Workflow,它的作用是通过 Alfred 来快速切换 DNS 服务器设置,默认支持几组常见的热门公共 DNS 服务器。

用法

在此之前,确认你的 Alfred 2 已经激活了 PowerPack 扩展功能。

然后从地址下载 Switch DNS Workflow,双击安装。

打开 Alfred 后,在文本框中输入 "sdns",从下拉列表中选取需要的 DNS 后,回车即可。

预设的 DNS 配置包括:

  • Default DNS: empty
  • Alibaba Public DNS::223.5.5.5 223.6.6.6
  • V2EX Public DNS: 199.91.73.222 178.79.131.110
  • 114 Public DNS: 114.114.114.114 114.114.115.115
  • Google Public DNS: 8.8.8.8 8.8.4.4
  • OpenerDNS: 42.120.21.30

示例

切换到 Alibaba Public DNS:

结果:

alfred-switchdns-result

更新日志

  • 2014.8.2 支持自定义配置 dns 列表

WordPress 阻挡垃圾评论

我的博客人气一般,但是垃圾评论却特别之多,严重影响我的心情。自从开博客以来,我一直都是通过 Akismet 插件来发现和过滤垃圾评论,效果非常不错,很少有漏网之鱼。但是前两天在阅读了云淡然同学写的文章wp_create_nonce实现wordpress垃圾评论终极防御之后,我突然萌生出自己写一些阻挡垃圾评论策略的想法。

wordpress-spam

下面我介绍几条本博客现在正在使用的阻挡垃圾评论的策略,几天下来效果还可以接受。每一种策略都不是完美的,所以只能多种方式配合使用。当然,道高一尺,魔高一丈,很多策略都必须要不断地改进与完善,并且最好根据自己的情况适当地调整。当然,如果你不想折腾,还是老老实实地使用 Akismet 插件来防护吧,插件的功能更加完善可靠,本文的方法只适合于不想启用过多插件和喜欢折腾的同学。

.htaccess 文件

首先我们可以借助 .htaccess 文件来阻挡部分恶意的垃圾评论,这一类评论往往是通过脚本或者工具自动提交的。请将以下内容添加到网站根目录的 .htaccess 文件中:

RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post\.php$
RewriteCond %{HTTP_REFERER} !.*kodango.com.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) http://%{REMOTE_ADDR}/$ [R=301,L]

上面的几条规则,可以阻挡来源不是你博客,或者 user agent 信息为空的机器人评论。

查看全文

WordPress 置顶文章推荐

新浪微博的置顶功能相信大家非常熟悉,其实 WordPress 早在 2.7 之后就拥有了文章置顶的功能。但是,实际上这个功能在大多主题上却没太多用武之地。我想其中的一个原因,是很多像我们这样的个人博客,首页基本上只展示最新的5-10篇文章,如果再置顶个几篇,首页的内容基本上就不变了。

不过,如果我们换个角度,把置顶文章从页面中央移到侧栏,这样的 效果应该会不错,首先首页的文章列表中不会受到置顶的干扰,同时位于侧栏的置顶文章又有类似文章推荐的效果,我们动手来试试。

整个解决方案需要考虑到两点:

  1. 首页展示文章的时候要忽略置顶文章,这里的忽略是指不置顶显示;
  2. 侧栏需要增加显示置顶文章列表的小工具;

步骤一:首页忽略置顶文章

在主题的 functions.php 中加入以下代码:

/*
 * Alter the main loop
 */
function dangopress_alter_main_loop($query)
{
    /* Only for main loop in home page */
    if (!$query->is_home() || !$query->is_main_query())
        return;

    // ignore sticky posts, don't show them in the start
    $query->set('ignore_sticky_posts', 1);
}
add_action('pre_get_posts', 'dangopress_alter_main_loop'); 

这里通过指定ignore_sticky_posts为1,查询出的文章列表就会忽略置顶文章。

查看全文

WordPress 使用 Google Code Prettify 高亮代码

Google Code Prettify 是 Google 开源的一个用于代码高亮的 Javascript 库,支持 C/C++, Java, Python, Ruby, PHP,Javascript 等等常见语言,目前包括 Google Code、Stackoverflow.com 在内的很多网站都在使用它。最吸引人的是,在使用它进行代码高亮时,甚至不需要指明语言类型,Prettify 会自动判断并处理。

google-code-prettify-javascript-syntax-highlighter

使用 Prettify 一般只需要包含两个文件:prettify.js 和 prettify.css,压缩过后的 prettify.js 大小差不多在 15K 左右,非常小巧。

简单使用

在网站页面中引用 Prettify文件:

<link href="prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="prettify.js"></script>

同时增加以下代码,让页面加载完成时执行 Prettify:

<script type="text/javascript">
window.onload = function(){prettyPrint();};
</script>

Prettify 会在网页中查找<pre class="prettyprint">...</pre>或者<code class="prettyprint">...</code>包围的代码片断,对它们进行高亮。

查看全文

WordPress 访客评论显示欢迎信息

最近逛了不少的博客,发现有一个共通的小细节:当你再次访问时,在评论框上方会显示类似“欢迎回来,xxx..”的信息。当时觉得这个想法挺不错的,一定程度上提高了用户体验,因为访客短期内再次访问时,不需要重复输入个人的信息。

关于这个话题,Neoease 有专门写过一篇文章来介绍如何实现 —— 提高 WordPress 访客评论时的用户体验。这次我在制作 dangopress 时,也顺手加上了这点。效果参考下图:

关键问题:获取访客信息

花点时间去研究,其实整个实现过程并不复杂。这里的关键点是,如何判断访客已经在近期发表过评论。

查看全文