在Mac上制作操作系统安装U盘

想要在一台机器上安装Linux,并且打算用U盘作为安装介质,于是开始在Mac上制作安装U盘安装盘。

Step 1

准备好所需资源:

  1. Linux光盘镜像文件
  2. U盘一个,容量应大于等于Linux光盘镜像文件的大小

Step 2

将U盘插入到Mac,此时Mac应该自动识别到U盘,并能够在Finder中的设备列表中看到U盘。
在Terminal中输入diskutil list命令查看已经挂载的U盘:

1
2
3
4
5
6
7
8
9
10
11
$ diskutil list
/dev/disk0
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *500.3 GB disk0
1: EFI EFI 209.7 MB disk0s1
2: Apple_HFS Macintosh HD 499.4 GB disk0s2
3: Apple_Boot Recovery HD 650.0 MB disk0s3
/dev/disk1
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *16.0 GB disk1
1: DOS_FAT_32 USB FLASH 16.0 GB disk1s1

可以看到U盘挂载到到了 /dev/disk1 ,不同情况下目标U盘挂载点可能有所不同,请注意识别,避免误操作其他的存储设备。

Step 3

接下来的操作需要U盘在非挂载的状态,所以我们来unmount这个U盘,这里用到的命令是diskutil unmountDisk:

1
$ sudo diskutil unmountDisk /dev/disk1

执行该命令后就无法在Finder中再看到该U盘了,但是通过diskutil list命令仍然能够看到。
关于 diskutil 的基本用法和参数,可以直接在终端输入diskutil命令并回车查看。

Step 4

现在可以开始向U盘写入已经准备好的Linux安装光盘镜像了,该操作需要用到dd命令:

1
$ sudo dd bs=4m if=~/Downloads/iso/debian-7.6.0-amd64-DVD-1.iso of=/dev/disk1

bs 用来指定输入和输出的块大小,我这里指定的是4兆字节, if 用来指定输入的源文件, of 用来指定输出的目标文件。如果iso文件较大,这个写入可能需要比较长的时间,在此过程中不会输出任何进度指示,需要耐心等待。

写入完成后,会打印类似下面的信息

1
2
3
939+1 records in
939+1 records out
3938795520 bytes transferred in 4847.252994 secs (812583 bytes/sec)

Done

现在已经完成了安装盘的制作,之后用这个U盘就可以在目的机器上安装写入的操作系统了。
补充一下,此方法适用与各种操作系统的安装。

阅读全文

MySQL 字符集相关

查看字符集

查看服务器字符集

1
SHOW VARIABLES LIKE '%char%';

查看数据库字符集

1
SHOW CREATE DATABASE db_name;

查看表的字符集

1
2
SHOW CREATE TABLE table_name;
SHOW TABLE STATUS FROM db_name LIKE '%TABLE_NAME%';

查看字段(列)字符集

1
SHOW FULL COLUMNS FROM table_name;

修改字符集

修改数据库默认字符集

1
2
ALTER DATABASE db_name DEFAULT CHARACTER SET character_name [COLLATE ...];
ALTER DATABASE my_db DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

修改表默认字符集

1
2
ALTER TABLE table_name DEFAULT CHARACTER SET character_name [COLLATE...];
ALTER TABLE my_table DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

修改表默认字符集,同时转换有关字段字符集

1
2
ALTER TABLE table_name CONVERT TO CHARACTER SET character_name [COLLATE ...]
ALTER TABLE my_table CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

修改字段(列)字符集:

1
2
ALTER TABLE table_name CHANGE col_name new_col_name CHARACTER SET character_name [COLLATE ...];
ALTER TABLE my_table CHANGE my_column my_column VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci;

在Mac下做文件转码

经常遇到从别人那里拿来的 Windows 下编辑的文本在 Mac 上打开全是乱码的问题,这时就需要对文件编码做一下转换才能正常阅读。

在 OS X 中可以用 iconv 命令来实现对文件转码:

1
iconv -f GB18030 -t UTF8 target.txt

批量转换如下:

1
2
cd target_files_dir
find *.txt -exec sh -c "iconv -f GB18030 -t UTF8 {} > {}.txt" \;

git 命令通过 HTTP 操作用 Gitlab 搭建的代码库出错

由于项目的需要近日升级了 MySQL 5.5,顺便也把 Gitlab 升级到了 6.7。结果今天在应用服务器上 git pull 的时候出现错误:

1
2
fatal: protocol error: bad line length character: 718
fatal: The remote end hung up unexpectedly

于是尝试了一下 git clone,也还是有错误:

1
fatal: protocol error: bad line length 8188

因为在我自己的电脑上 git 操作一切正常,而两个环境主要的区别就是连接 git 服务的协议,我的机器上用基于 sshgit 协议,而应用服务器上通过 http 协议访问服务。所以问题肯定是和 http 协议有关,于是开始查看 gitlab 的日志,但是看不出有什么问题,查看 Nginx 的日志也没有任何错误。

最后,经过一番搜索,找到了这个Issue
看来是和这个代码有关系。在这个代码里面,对原来直接返回的 block 内容用 encode_chunk 方法重新进行了封装,在原来的 block 前添加了一行块大小信息

由于我现在的 Nginx 是 1.0 的版本,这个版本默认是没有包含 chunking module 的,所以无法正确处理 chunked response,看来只要按大家说的升级 Nginx 就可以了。

我之前是直接通过 yum install 安装的 Nginx,而默认的 yum 封包库里只有 Nginx 1.0,所以我添加了 Webtatic 的封包库,然后卸载 Nginx 1.0,安装 Nginx 1.4。

1
2
3
4
5
rpm -Uvh http://mirror.webtatic.com/yum/el6/latest.rpm
service nginx stop
yum remove nginx
yum install nginx14
service nginx start

整个升级过程非常快,我事先还备份了 /etc/nginx,但是升级后发现配置文件都还在,而且启动 Nginx 1.4 十分顺利。再尝试 git pull,果然OK了!

HTTP_ACCEPT 是 'application/json, */*' 时 Rails 按 'text/html' 处理

用 Rails3 做移动端 App 的 Backend 时,出现一种情况,当移动端使用中国移动的网络时(中国联通无此状况),发送到服务端的 HTTP 请求的 Header 中的 Accept 莫名其妙的的被加上了 */*。而本来客户端只给 Accept 赋值了 application/json,现在就变成了 application/json, */*。Rails 在接收到这种请求时,request 的 format 就会识别为 text/html,导致 controller 最终返回给客户端的是 html 格式的应答。

为什么会被添加 */* 就不做深究了,网络运营商对数据的传输做了哪些处理策略不得而知,就算知道了也无能为力。于是考虑从服务端着手想办法解决。

之前为了发现为什么 Rails 返回的是 html 格式的应答时添加了一些 debug 日志,来观察客户端有没有正确的设置 HTTP Header。

app/controllers/application_controller.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :log_request
def log_request
logger.debug "HTTP_ACCEPT = #{request.headers['HTTP_ACCEPT']}"
logger.debug "CONTENT_TYPE = #{request.headers['CONTENT_TYPE']}"
logger.debug "request.content_type = #{request.headers['action_dispatch.request.content_type']}"
logger.debug "request.accepts = #{request.headers['action_dispatch.request.accepts']}"
logger.debug "request.formats = #{request.headers['action_dispatch.request.formats']}"
end
end

正是根据这些日志发现了被添加的 */*,而且发现只有这一种情况会导致返回 html 应答,所以就针对这种情况做一下处理。
application_controller.rb 中添加如下代码:

1
2
3
4
5
6
7
8
9
before_filter :modify_request_header
def modify_request_header
if request.headers['HTTP_ACCEPT'].include? "*/*"
preferred_accept = request.headers['HTTP_ACCEPT'].split(",").first
logger.debug "Preferred ACCEPT: #{preferred_accept}"
request.format = :json if preferred_accept == "application/json"
end
end

采用这种方式修改了 request.formats 的值,于是终于可以正确返回 json 格式的应答了。

可是为什么 Rails 不按照 Accept 的值的顺序优先采用 application/json 指定的格式呢?

阅读全文

Rails 环境变量设置

什么是环境变量(Environment Variables)

所有的操作系统都提供了各自的机制可以设置环境变量,所有的 Unix类Unix 系统中的每个进程都有各自的环境变量设置,很多 PaaS 的开发者平台(比如Heroku)也提供了配置环境变量的机制。我的理解是,环境变量就是可以在不同环境中单独配置(对环境有依赖),可以让进程在运行时加载并使用,一些底层的基础变量。常见的环境变量比如:PATH、HOME 等等。

为什么在 Rails 中使用环境变量

主要有两方面原因,

  • 应用程序通常都是设计成可以在多种不同环境下部署和运行的,所以代码中不应该出现针对特定环境的内容(比如文件绝对路径),而是应该在运行时根据当前环境使用合适的内容。那么对与这些对环境有所依赖的部分,就可能需要使用环境变量来进行配置。
  • 当应用程序中需要使用一些涉及到安全和隐私的内容时(比如邮箱密码),把这类内容直接写在代码里是很不明智的,因为可能会有很多人可以浏览这部分代码,或者这些代码根本就是开源的。为了保护此类数据,就有必要把它们配置在只有你自己可以访问的环境中,让程序在运行时根据变量名去获取。

怎样在 Rails 中获取环境变量

Ruby 提供了一个很方便的访问环境变量的方式:

1
ENV["VARIABLE_NAME"]

比如要在一个 Rails 应用中配置一个 Gmail 账号来发邮件:

1
2
3
4
5
6
7
8
9
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: "example.com",
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"]
password: ENV["GMAIL_PASSWORD"]
}

这个配置对 Rails 开发者肯定不陌生,这里就是使用环境变量对 Gmail 的用户名和密码进行了保护。

如何配置环境变量

配置环境变量对大多数人来说也并不陌生,比如 Windows 系统属性设置里面就可以找到配置环境变量的按钮,在 Linux/Unix/Mac 之类的操作系统中可以通过配置 .bashrc 或者 .zshrc (根据使用shell来定)之类文件来设置。

比如在 ~/.bashrc 中加入下面内容:

1
2
export GMAIL_USERNAME="foobar@gmail.com"
export GMAIL_PASSWORD="password"

阅读全文

Joining lines without spaces in VIM

在VIM中合并多行文本且其中不产生空格

假设有一个文本文件,里面有很多行文本,我现在想要把所有文本合并为一行。
这不是很简单嘛!
只要 gg 先移动到首行,再 VG(用vG也可)选中所有行,然后用 J 合并所有行不就OK了么?

按上面的操作的确是合并成了一行,可是在原来每两行的连接处都会被添加一个空格,这不是我想要的。
要把所有文本合并为一行且中间不添加空格,该怎么做?
其实也很简单,在 J 之前再多敲一个 g 就可以了,连续的操作就是 ggVGgJ

那要是不合并全部文本,只合并一段(paragraph)文本,该怎么做?
可以这样操作 vipgJ,也就是在visual模式下选中段落然后 gJ

以此类推,基本的方法就是在visual模式下选中要合并的部分 gJ 一下就好。