在 Mac OS X 上安装lighttpd

在 Mac OS X 上安装lighttpd

Install lighttpd in Mac OS X

2014-10-22更新: 加入更新到 Yosemite 后出现错误的解决方法。

在Windows上,我使用的是XAMPP套件。

Mac上我还没有安装HTTP服务器。我的VPS上使用的是lighttpd(从Apache到Lighttpd),因此在工作电脑上也希望使用它。

安装

-> % brew search lighttpd
lighttpd
-> % brew install lighttpd

安装过程中,有几个重点需要提醒: 继续阅读在 Mac OS X 上安装lighttpd

升级Mountain Lion的bash到4.2版本

升级Mountain Lion的bash到4.2版本

Mountain Line自带的Bash是3.2.58版本,这个版本不支持关联数组的定义。

而我以前写的脚本中,大量使用了关联数组。因此,我需要将Bash升级到4.2版本。

安装GCC

如果GCC编译器没有安装,那么需要去Apple Developer 下载Command Line Tools。我下载的是 Command Line Tools(OSX Mountain Lion) for Xcode,文件大小为118MB。

下载bash源码

curl https://ftp.gnu.org/gnu/bash/bash-4.2.tar.gz -o ~/Downloads/bash42.gz
tar xzf ~/Downloads/bash42.gz

编译和安装

cd ~/Downloads/bashr42
./configure && make && sudo make install

使用新的bash

新安装的bash在/usr/local/bin/bash,与旧的bash并不冲突,需要设置当前用户使用它。

chsh -s /usr/local/bin/bash {user_name}
sudo bash -c "echo /usr/local/bin/bash >> /private/etc/shells"

关闭终端并重新打开,输入bash -versionhelp。查看bash安装情况。

替换旧的bash

sudo mv /bin/bash /bin/bash3.2.58
sudo ln -s /usr/local/bin/bash /bin/bash

参考文章

在bash中替换屏幕上显示的行

在bash中替换屏幕上显示的行

在编写一些比较耗时的程序时,我经常需要在屏幕上显示一些进度信息。默认的echo在输出的时候,会将每一条进度信息换行显示,就像下面这样:

for i in {1..3};do
    sleep 1
    echo "第$i次"
done
# 输出
第1次
第2次
第3次

如果希望每次显示替换掉前一次显示,可以这样处理:

for i in {1..3};do
    sleep 1
    echo -en "\r第$i次"
done

-n 参数的作用是不在echo的结尾自动加入换行符,-e 参数的作用是对反斜杠字符进行转义。把它们用在一起,对输出文本中的 \r 进行了转义,相当于在上一行内容之后输入了一次回车,清空了当前行的显示。

下面的代码运行后,“倒计时完毕”字样会紧接在“第3次”之后,这个应该如何处理呢?

for i in {1..3};do
    sleep 1
    echo -en "\r第$i次"
done
echo '倒计时完毕'

使用bash从SVN和Git中获取顺序版本号

使用bash从SVN和Git中获取顺序版本号

在进行自动部署的时候,经常需要用脚本获取程序的最新版本号,下面是我的两个解决方案。

for SVN

# 获取XML版本的svn信息,这样可以避免不同语言的问题
xml=`svn info --xml --incremental`
# 我们可以获取到2个版本号,一个是最新版本库版本号,一个是自己的提交版本号。删除自己提交的版本号。
revision=`echo "$xml"|sed '/revision/!d'|sed '$d'`
# 提取出版本号的数字部分
echo $revision|sed 's/revision="\([0-9]\+\)">\?/\1/'

for Git

Git采用的是SHA散列码作为版本号,因此它没有顺序的版本号。但我们可以通过统计Git版本库的提交次数来获得一个顺序版本号。

# 基准版本号默认是1,可以通过传递一个参数修改
get_version()
{
    local base=${1:-1}
    echo $((`git rev-list --all|wc -l` + $base))
}
get_version 7000

这个版本对网上搜到的那个被普遍转载的版本做了简化和调整。网上那个版本写得比较复杂,例如awk的使用没有必要,而且要统计所有提交,应该用 git rev-list --all 参数,而不是用 git rev-list HEAD

在Bash中将字符串拆分成数组

在Bash中将字符串拆分成数组

split string to array in bash

和AS中的String.split不同,Bash没有类似的语法,但它实在是太灵活了,有很多种方式可以做类似的事情。

以前我写过一篇 Bash数组操作教程 ,今天使用Bash做文件处理的时候,发现有必要再写一篇将字符串拆分成数组的教程。但发现有人已经写了更好的教程在前面了,于是就偷懒转过来好了。 继续阅读在Bash中将字符串拆分成数组

Bash的=~正则表达式匹配~旧文章害死人啊

很简单的一个匹配ip地址的测试,死活就是匹配不了:

newip='192.168.1.100'
if [[ "$newip" =~ '^([0-9]{1,3}\.){3}[0-9]{1,3}$' ]];then
    echo '找到了ip地址'
fi

翻遍了google中的中文资料,都没发现问题。最后终于用英文搜到《Advanced Bash-Scripting Guide》中的一篇介绍Bash版本的文章,其中写道: 继续阅读Bash的=~正则表达式匹配~旧文章害死人啊

修改了SSH默认端口之后,如何配置git?

由于安全或者其它原因,我们可能会修改默认的SSH服务端口号,默认情况下,已有的git项目在pull或者push的时候会报错。

现在假设原来的项目的remote设置为git@domain.com:Projects/p1.git,将服务器SSH默认端口修改为3022后,导致push出错。

有两个解决办法: 继续阅读修改了SSH默认端口之后,如何配置git?

在bash中使用DNSPod的API接口实现DDNS客户端

  • 2012-03-12更新
    判断DNSPOD API返回值为空的情况,这种情况每天会出现2-3次,这种情况不退出程序,而是继续等待;
  • 2012-03-11更新
    • 调整了部分正则表达式的写法;
    • 增加了错误判断功能。
  • 2012-03-10 更新
    支持多域名多记录。
    • 多域名使用数组定义,每个元素代表一个域名的一组要更新的子记录;
    • 仅支持A记录的更新,因为其他类型的记录可能有重名的情况出现;
    • 每一组记录,以空格分隔域名和子域名;
    • 第一个空格前为主域名,后面用空格分离多个子域名;
    • 如果使用泛域名,必须用 \* 转义。

以下为要更新的域名范例:

domainList[0]='domain1.com \* @'
domainList[1]='domain2.com www subdomain1 subdomain2'

使用方法:

  • 配置domainList数组,详细内容见上方;
  • 配置delay的值,多长时间检测一次ip变化,单位是秒。

继续阅读在bash中使用DNSPod的API接口实现DDNS客户端

Bash数组操作教程

Bash数组操作教程

一、定义数组

1. 使用[]操作符

names[0]='zrong'
names[1]='jacky'

2. 使用()直接赋值

names=('zrong' 'jacky')
# 或
names=([0]='zrong' [1]='jacky')

3. 使用declare -a定义数组。这种方法可以将一个空的变量定义成数组类型。

declare -a names

4. 从文件中读取数组

cat>names.txt
zrong
jacky
sweet
Ctrl+C
# 将每一行读取为数组的一个元素
names=(`cat 'names.txt'`)

二、读取数组

1. 数组取值

和ActionScript一样,Bash也使用[]操作符和基于0的下标来取值:

adobe=('Flash' 'Flex' 'Photoshop')
echo ${adobe[0]}
# 打印
# Flash

2. 数组长度(元素个数)

使用“@”这个特殊的下标,可以将数组扩展成列表,然后就可以使用bash中的获取变量长度的操作符“#”来获取数组中元素的个数了:

adobe=('Flash' 'Flex' 'Photoshop')
echo ${#adobe[@]}
# 打印
# 3

有趣的是,没有定义的数组下标,并不会占用数组中元素的个数:

adobe=([0]='Flash' [2]='Flex' [4]='Photoshop')
echo ${#adobe[@]}
# 打印
# 3

3. 获取数组的一部分

命令替换对数组也是有效的,可以使用偏移操作符来取得数组的一部分:

adobe=('Flash' 'Flex' 'Photoshop' 'Dreamweaver' 'Premiere')
echo ${adobe[@]:1:3}
# 打印
# Flex Photoshop Dreamweaver
echo ${adobe[@]:3}
# 打印
# Dreamweaver Premiere

4. 连接两个数组

adobe=('Flash' 'Flex' 'Photoshop' 'Dreamweaver' 'Premiere')
adobe2=('Fireworks' 'Illustrator')
adobe3=(${adobe[@]} ${adobe2[@]})
echo ${#adobe3[@]}
# 打印
# 7

三、修改数组

1. 替换数组元素

模式操作符对数组也是有效的,可以使用它来替换数组中的元素

adobe=('Flash' 'Flex' 'Photoshop' 'Dreamweaver' 'Premiere')
echo ${adobe[@]/Flash/FlashCS5}
# 打印
# 注意,打印的结果是一个字符串列表,不是数组
# FlashCS5 Flex Photoshop Dreamweaver Premiere
#
# 将替换后的值重新保存成数组
adobe=(${adobe[@]/Flash/FlashCS5})

2. 删除数组元素

使用命令替换并重新赋值的方式删除数组元素

# 删除Photoshop元素
adobe=('Flash' 'Flex' 'Photoshop' 'Dreamweaver' 'Premiere')
adobe=(${adobe[@]:0:2} ${adobe[@]:3})
echo ${adobe[@]}
# 打印
# Flash Flex Dreamweaver Premiere

使用模式操作符删除数组元素

adobe=('Flash' 'Flex' 'Photoshop' 'Dreamweaver' 'Premiere')
adobe=(${adobe[@]/Photoshop/})
echo ${adobe[@]}
# 打印
# Flash Flex Dreamweaver Premiere

四、循环

使用for in循环读取数组:

adobe=('Flash' 'Flex' 'Photoshop' 'Dreamweaver' 'Premiere')
for item in ${adobe[@]};do
    echo $item
done
# 打印
# Flash 
# Flex 
# Photoshop 
# Dreamweaver 
# Premiere

使用for循环读取数组:

adobe=('Flash' 'Flex' 'Photoshop' 'Dreamweaver' 'Premiere')
len=${#adobe[@]}
for ((i=0;i<$len;i++));do
    echo ${adobe[$i]}
done
# 打印
# Flash 
# Flex 
# Photoshop 
# Dreamweaver 
# Premiere

在git中批量重命名

  • 2011-09-09更新:为《学习Bash(第二版)》PDF手工加入书签。
  • 2011-09-20更新:加入《Learning.The.Bash.Shell.3rd》下载。

有一批形如 map_XXX.XXX 的文件,要改名为 map1_XXX.XXX 。如果使用其他改名工具改名,git 会认为是删除了这些文件,并要求将改名后的文件重新添加到版本库,这会无端的增加版本库的大小。

最好的办法当然是用git mv来处理。鼓捣了半小时,写了我的第一行BASH代码:

for i in map*{jpg,xml};do git mv $i "map1${i:3}";done

说明:

  • map*{jpg,xml} 是只处理jpg和xml文件;
  • $i 是引用循环中的文件名,和 ${i} 的作用相同;
  • ${i:3} 返回文件名的第3至最后一个字符的字符串。

BASH真的很好玩,推荐两本书:

《高级 Bash 脚本编程指南》(Advanced Bash-Scripting Guide)

  学习Bash第二版(完美书签) (5.1 MiB, 1,432 hits)

上面这本书扫描的很不清晰,很多代码看不清,最好是对照英文版来看,下面是英文版下载:

  Learning.The.Bash.Shell.3rd (714.3 KiB, 1,093 hits)