mark-directory: 快速目录切换工具

今天早上看到@程序员的那些事转的一条微博《使用命令行快速操控文件系统》,文中作者介绍了他提升工作效率的一个命令行小工具,可以快速切换工作目录,我觉得蛮有意思的,小小研究了下。在原工具的基础上,我在 Github fork了一个改进的版本 —— mark-directory,具体可以看文章最后。

工作原理

这个小工具的工作原理非常简单,相信大家扫过一遍原文就可以明白,它创建了一个隐藏目录(例如~/.marks),目录里面存放的文件都是常用目录的软链接。我们可以将这个软链接看作一个书签,通过访问这个书签我们可以方便地跳转到相应的目录。

具体实现

这个小工具也提供了相应的命令来管理这些软链接文件,当前支持的是jump, mark, unmark和marks。

以上4个操作命令的实现代码如下所示,非常简单:

export MARKPATH=$HOME/.marks
function jump { 
    cd -P "$MARKPATH/$1" 2>/dev/null || echo "No such mark: $1"
}
function mark { 
    mkdir -p "$MARKPATH"; ln -s "$(pwd)" "$MARKPATH/$1"
}
function unmark { 
    rm -i "$MARKPATH/$1"
}
function marks {
    ls -l "$MARKPATH" | sed 's/  / /g' | cut -d' ' -f9- | sed 's/ -/\t-/g' && echo
}

将这段代码放到~/.bashrc 文件中。接下来我们来尝试使用这个小工具。

查看全文

Bash Pitfalls: 编程易犯的错误(四)

上一篇文章参见Bash Pitfalls: 编程易犯的错误(三)。这一篇翻译得不是非常满意,时间比较赶,请见谅,如果有问题可以在本文后方留言,大家一起深入探讨。

36. [ -n $foo ] or [ -z $foo ]

这个例子中,$foo 没有用引号引起来,当$foo包含空格或者$foo为空时都会出问题:

$ foo="some word" && [ -n $foo ] && echo yes
-bash: [: some: binary operator expected

$ foo="" && [ -n $foo ] && echo yes
yes

正确的写法是:

[ -n "$foo" ]
[ -z "$foo" ]
[ -n "$(some command with a "$file" in it)" ]

[[ -n $foo ]]
[[ -z $foo ]]

37. [[ -e "$broken_symlink" ]] returns 1 even though $broken_symlink exists

这里-e 选项是看文件是否存在,当紧跟的文件是一个软链接时,它不看软链接是否存在,而是看实际指向的文件是否存在。所以当软链接损坏时,即实际指向的文件被删除后,-e 的结果返回1。

查看全文

Bash Pitfalls: 编程易犯的错误(三)

上一篇文章参见Bash Pitfalls: 编程易犯的错误(二)

24. for arg in $*

和大多数 Shell 一样,Bash 支持依次读取单个命令行参数的语法。不过这并是$*或者$@,这两种写法都不正确,它们只能得到完整的参数列表,并非单独的一个个参数。

正确的语法是(没错要加上引号):

for arg in "$@"

# 或者更简单的写法
for arg

在脚本中遍历所有参数是一个再普遍不过的需求,所以 for arg 默认等价于 for arg in "$@"。$@使用双引号后就有特殊的魔力,每个参数展开后成为一个独立的单词。("$@"等价于"$1" "$2" "$3" ...)

下面是一个错误的例子:

for x in $*; do
   echo "parameter: '$x'"
done

执行的结果为:

$ ./myscript 'arg 1' arg2 arg3
parameter: 'arg'
parameter: '1'
parameter: 'arg2'
parameter: 'arg3'

正确的写法:

for x in "$@"; do
   echo "parameter: '$x'"
done

执行的结果为:

$ ./myscript 'arg 1' arg2 arg3
parameter: 'arg 1'
parameter: 'arg2'
parameter: 'arg3'

查看全文

Bash Pitfalls: 编程易犯的错误(二)

上一篇文章参见Bash Pitfalls: 编程易犯的错误(一)

13. cat file | sed s/foo/bar/ > file

你不应该在一个管道中,从一个文件读的同时,再往相同的文件里面写,这样的后果是未知的。

你可以为此创建一个临时文件,这种做法比较安全可靠:

# sed 's/foo/bar/g' file > tmpfile && mv tmpfile file

或者,如果你用得是 GNU Sed 4.x 以上的版本,可以使用-i 选项即时修改文件的内容:

# sed -i 's/foo/bar/g' file

14. echo $foo

这种看似无害的命令往往会给初学者千万极大的困扰,他们会怀疑是不是因为 $foo 变量的值是错误的。事实却是因为,$foo 变量在这里没有使用双引号,所以在解析的时候会进行单词拆分文件名展开,最终导致执行结果与预期大相径庭:

msg="Please enter a file name of the form *.zip"
echo $msg

这里整句话会被拆分成单词,然后其中的通配符会被展开,例如*.zip。当你的用户看到如下的结果时,他们会怎样想:

Please enter a file name of the form freenfss.zip lw35nfss.zip

查看全文

WordPress 侧栏实现 Tab 选项卡

有时候我们希望在侧栏放更多内容,但是容易让侧栏显得过长。网上比较常见的做法是,用 Tab 选项卡的形式将多个小工具合并到一起,例如热门文章、最新文章、随机文章等等,这样同样的空间包含的内容更多,用户体验也增强不少。

网上可以下到不少类似的插件,也有很多非插件的实现方式。我使用了William同学WordPress侧边栏JQuery版TAB选项卡文章中介绍的方法来实现,效果可以看我的博客侧栏:

查看全文

Javascript DOM 笔记

HTML文档可以看成由各种 DOM 节点组成的文档树,例如:整篇文档是一个文档节点;第个标签都是一个元素节点;文本内容可以看成文本节点;标签属性是属性节点,甚至注释也是注释节点。

nodeType

元素节点的类型可以通过node.nodeType访问,例如:

document.nodeType           # 9

主要的节点类型如下所示:

Element Type Node Type
Element 1
Attribute 2
Text 3
Comment 8
Document 9

查看全文

Browser detect 脚本分析

目前浏览器检测 (Browser detect) 一般有两种方法:

  • 基于userAgent的值的检测;
  • 基于对象的检测,即object detection;

而第一种方法,一般来说效果并不是非常理想,因为许多浏览器都允许用户更改userAgent的值,起因要追究于第一次浏览器大战(PPK on Javascript p57)。因此,这一类的检测都不是万能的,无论是基于navigator.userAgent还是navigator.vendor等,浏览器总有办法绕过这一层检测。

PPK 在他的一篇文章中提供的检测脚本其实也是基于navigator的,但是他在整个脚本的设计上非常细致,覆盖了许多细节,看了之后收获很大。首先使用了下ppk的检测脚本,博客首页右方检测浏览器的功能正是使用ppk的脚本。

例子

当时看脚本的时候还是有点迷糊,因为脑子里面对各个浏览器的userAgent内容非常模糊,其实自己就用过Firefox、Chrome、IE、Opera等几个浏览器,没试过Safari、Konqueror、iCab等等。回头看完了脚本,我就把自己电脑上有的浏览器的userAgent都看了一遍并列了出来:

Opera/9.80 (Windows NT 6.1; U; Edition IBIS; en) Presto/2.6.30 Version/10.60
Mozilla/5.0 (Windows NT 6.1; rv:2.0b8pre) Gecko/20101029 Firefox/4.0b8pre
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.41 Safari/534.7
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; AskTB5.6)

然后是脚本检测的结果分别是:

You're using Opera 9.8 on Windows !
You're using Firefox 4 on Windows !
You're using Chrome 7 on Windows !
You're using Explorer 9 on Windows !

查看全文

Backup Mediawiki 站点

去年,我使用 Mediawiki 搭建了一个 wiki 站点,用于团队知识积累。短短半年,已经有不少的沉淀,随着 wiki 越来越重要,它的数据安全性也必须考虑起来,因此我们准备把 wiki 迁移到 VM 上,并且考虑做好备份。迁移之前,数据备份的操作是件体力活,不过好在网上有不少的文章介绍如何操作, Mediawiki 官方也有专门的文章来介绍具体的操作过程以及需要注意的地方,详见Backing up a wiki

文章的最后还引用了一系列的备份脚本,这是我等懒人最喜欢的方法,越简单粗暴越好。看了其中的一个脚本(Backing up a wiki/Duesentrieb's backup script - MediaWiki),脚本的内容很简单,不过要想 run 起来,首先还得改动开头的几处配置,比较麻烦。

所以我自己 fork 了一个新的版本,通过命令行参数的形式提供配置,并且修复了脚本的几处 Bug,例如备份目录没有创建、输出信息中的转义字符串没有显示等等。

查看全文