vim – 查按鍵定義

Embed from Getty Images

雖說常用 vim,但是我幾乎是沒什麼在定義按鍵,都是沿用 plugin 的定義,所以用了一堆 plugin 之後,難免會遇到衝突的情況。

那麼要怎麼查按鍵的定義呢?除了可以用 grep/ag 來找 vimrc/plugin 裡的定義之外,也可以在執行 vim 以後,用 :verbose map 來查

" 我的 leader key 是 \
" 以下就是查 \gg 會執行的指令
:verbose map <leader>gg

步驟:

  1. 先按冒號 ‘:’ ,游標會移到下方,進入 last line mode
  2. 在下方輸入 verbose map <leader>gg
  3. 輸入完按 Enter,就會看到 vim 印出按鍵的定義與上次定義的位置
  4. 再按一次 Enter,就會關閉回到 Normal mode

印出的結果 (會因為你的按鍵定義而異)

n  \gg         * :EXGSearchCWordW
        上次設定: ~/exvim/vimfiles/bundle/ex-utility/autoload/ex/keymap.vim line 37

算IOPS

上個月公司 AWS 帳單來時,看到 EBS 使用率提高,所以費用增加不少

剛剛去算了一下目前的 IOPS ,然後套到 aws 計算機去算。

先用 AWS CloudWatch 去指定要看的 EBS volume 、指標(VolumeReadOps/VolumeWriteOps)以及日期區間,把統計方式改為總和,然後用最高點的數值套這公式: (VolumeReadOps + VolumeWriteOps) / 區間的秒數,算出目前用的 IOPS 是 106 左右。

計算方式是參考這兩個連結:

然後到 AWS 計算機網頁,目前 EBS volume type 是 magnetic(standard),storage  250 G,IOPS 填入 106,算出金額約 39.79,接著將 Volume type 改為 gp2,金額變成 26.40。

所以選擇適當的 EBS volume type 是有助於省錢的。

jemalloc

jemalloc (github) 是效能聽說很好的 malloc library。

之前是在 為線上環境而最佳化的 Ruby:Fullstaq Ruby 看到的,看到的當下是想說,會不會也有人來編譯用 jemalloc 的 Python 版本,不過很遺憾的是沒有。後來找了 jemalloc 的資料以後,發現要替換其實不難。Ubuntu 14.04 是已經有包 libjemalloc 了,但版本較舊,是 3.5.1 版。

後來還是選擇自行編譯,然後使用 LD_PRELOAD 環境變數來替換 python 的 malloc library。

那要怎麼檢查 python 是不是真的有使用到呢?這可以使用 lsof 來檢查。(How to see the currently loaded shared objects in Linux?)

lsof /usr/local/lib/libjemalloc.so.2

同款的還有 tcmalloc (Google 出的),有空也來測試看看。

P.S. ptmalloc 是 glibc 的 malloc。

Linux 裡也能用 MacOSX

之前是知道 VirtualBox 可以執行 MacOSX,但我一直沒試過。前幾天,在 Twitter 上看到這個專案:https://github.com/foxlet/macOS-Simple-KVM/ ,說可以用 Linux 的 KVM 來執行 MacOSX。

今天來試試看,基本上不用做太多修改,就可以順利開機起來。
這邊紀錄一下幾件遇到的情況:

  1. 不需要額外設定 Bridged network:原本以為網路需要用 Bridged,結果照著網站上的說明去設定,反而網路有問題,這會導致安裝程序無法進行。
  2. Disk utility:到安裝程式時,先選 Disk utility 去初始化之前用 qemu-img 所建立的磁碟,後續才選 Reinstall 那個項目。
  3. 安裝以後的重開機:安裝以後重開機,不要再選到安裝,要注意看一下,選到從 SystemDisk 開機那個項目 (從右邊數過來第二個)
  4. virt-manager:可以安裝 virt-manager ,會有個類似 virtualbox 的管理工具 (就只是類似,不代表一模一樣)。這邊有幾件事情要做:
    1. 安裝:sudo apt-get install virt-manager
    2. 加入 kvm 群組:sudo usermod -a -G libvirt,kvm <your_username> ,做完這步要重新開機,virt-manager 才能順利連接 QEMU/KVM。
    3. virt-manager 是在系統工具裡,中文名字是虛擬機管理員。
    4. 使用 ./make.sh –add 將機器組態匯入以後,如果有遇到不能開機的情況,可以參考這個 pull request,使用這個指令 qemu-system-x86_64 –machine help | grep q35 | cut -d” ” -f1 | egrep -oe “.*-[0-9.]+” | sort -rV | head -1 取得 machine type,修改 template.xml 以後,再用 sudo virsh define ./template.xml 去更新機器組態。
    5. 要用虛擬機管理員自行新增硬碟。

安裝以後的設定:

  1. 輸入法:不使用 CapsLock 切換輸入法,改用 ctrl-space 來切換的話,第一步是在系統偏好設定 > 鍵盤 > 輸入方式那邊,將「使用大寫鎖定鍵來切換…」的那個勾選給取消掉。然後到系統偏好設定 > 鍵盤 > 快捷鍵那邊,在左邊找到輸入方式,將右邊的兩個項目給勾選起來,這樣就可以用 ctrl+space 來切換輸入法了,長按住 ctrl,再按 space 則是切換輸入法。
  2. homebrew:就是安裝常看到的 brew 指令。

MySQL 到底有沒有 case sensitive ?

公司的程式有人回報說,在搜尋電子郵件時,沒有區分大小寫 (case insensitive),我心裡想,雖然電子郵件並沒有嚴格區分大小寫,但我應該沒有特別做這件事,照理說,是要有區分大小寫才是,於是我開始看程式碼去找是不是 Django 等框架/函式庫自動加上了。

不過我找了好一陣子都沒找到,看來應該不是程式的問題。既然不是程式問題,那就可能是資料庫問題了,我在開發環境的 SQLite 裡用 SELECT SQL 查詢,有區分大小寫;生產環境是用 MySQL,我改在 MySQL shell 用 SELECT SQL 來查詢。結果,真的是資料庫設定問題,上網搜尋,才確定真的是 MySQL 問題:

簡單的說,是 collation 問題,所以解決方法也算是簡單,一個方法是改變 collation,看是要資料庫整個改,還是個別 table/column 去改;一個方法則是改 column data type。

MySQL 手冊對 collation 的說明是這樣的 (連結),只要後綴是 _cs 的或是 _bin 的,都是 case-sensitive 的。改 collation ,可以先使用 SHOW COLLATION WHERE COLLATION LIKE “%_cs” 來找,但 utf8 是沒有後綴名為 _cs 的 collation,只能使用 utf8_bin 。找到合適的 collation 後,要改指定 column data type ,可以使用 ALTER TABLE documents__document CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;

以 Django 來說,當然最好是一開始在建立資料庫時,就指定好 charset 跟 collation,之後的作法就是自己寫 Migration 執行自訂的 SQL 來變更指定欄位的 data type 了。

Serveo.net

網址:https://serveo.net/
找 ngrok alternative 時,找到這個用 ssh 指令就可以破牆,挺方便的。

例子1

Port forwarding

在 A 電腦裡輸入

ssh -R 80:localhost:3000 serveo.net

按下 yes,會拿到一個類似 https://talis.serveo.net 的網址,當從另外一台電腦連到此網址時,會連接到 A 電腦的 port 3000

P.S. 

  1. 要拿到不一樣的網址,就帶 username,例如:ssh -R 80:localhost:8888 foo@serveo.net
  2. localhost 可以替換為其他電腦,例如 192.168.1.1

例子2

ssh port forwarding

在 A 電腦裡有 SSH server,然後輸入

ssh -R myalias:22:localhost:22 serveo.net

接著在其他電腦有 ssh client 的電腦裡輸入

ssh -o ProxyCommand="ssh -W myalias:22 serveo.net" user@myalias

就可以連接到 A 電腦的 SSH server

P.S.

  1. OpenSSH client 7.3 以後可以用 -J 參數:ssh -J serveo.net user@myalias

用 autossh 自動重連

事前預備

  1. sudo adduser –system –group –disabled-password autossh
  2. sudo chsh –shell /bin/false autossh
  3. 預先使用 autossh ,執行過一次 autossh 指令

autossh + upstart

# /etc/init/autossh.conf
# http://logan.tw/posts/2014/12/15/autossh-and-ubuntu-upstart-daemon/
description "autossh daemon for ssh tunnel"
start on net-device-up IFACE=br0 # 此處需因應網路裝置來調整為 eth0, eth1 ...
stop on runlevel [01S6]

setuid autossh
respawn
respawn limit 5 60
script
#export AUTOSSH_FIRST_POLL=30
#export AUTOSSH_GATETIME=0
#export AUTOSSH_POLL=60
autossh -M 0 -R pokemon22:22:localhost:22 serveo.net
end script

autossh + systemd

# /etc/systemd/system/autossh.service
# https://gist.github.com/thomasfr/9707568
[Unit]Description=Keeps a tunnel to 'serveo.net' open
After=network-online.target

[Service]
User=autossh
# -p [PORT]
# -l [user]
# -M 0 --> no monitoring
# -N Just open the connection and do nothing (not interactive)
# LOCALPORT:IP_ON_EXAMPLE_COM:PORT_ON_EXAMPLE_COM
# ExecStart=/usr/bin/autossh -M 0 -N -q -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -p 22 -l autossh remote.example.com -L 7474:127.0.0.1:7474 -i /home/autossh/.ssh/id_rsa
ExecStart=/usr/bin/autossh -M 0 -R pokemon22:22:localhost:22 serveo.net

[Install]
WantedBy=multi-user.target

s3proxy

網址:https://github.com/gaul/s3proxy
可以在本機端測試 S3,而不需要去開 S3 bucket 跟弄 AWS credential ,s3proxy 提供了跟 S3 一樣的 API 介面。

boto3 可以用,用法參考這邊:https://github.com/gaul/s3proxy/wiki/Client-compatibility-list

# Python3 + boto3 example
session = boto3.session.Session(aws_access_key_id='identity',
                                aws_secret_access_key='credential')
config = boto3.session.Config(s3={'addressing_style': 'path'})
# low level S3 client
client = session.client('s3', endpoint_url='http://localhost:60080',
                        config=config)
# S3 resource object
resource = session.resource('s3', endpoint_url='http://localhost:60080',
                            config=config)

用 docker 快速啟動

mkdir -p /tmp/data
docker run --publish 60080:80 -v /tmp/data:/data --env S3PROXY_AUTHORIZATION=none andrewgaul/s3proxy

django-storage 的話,應該是要改設定裡的 AWS_S3_ENDPOINT_URL

goaccess

安裝

# 最新版
echo "deb http://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee -a /etc/apt/sources.list.d/goaccess.list
wget -O - https://deb.goaccess.io/gnugpg.key | sudo apt-key add -
sudo apt update && sudo apt install goaccess

要可以使用 –keep-db-files 得安裝 goaccess-tcb

使用

詳細的使用可以看 手冊,以下是常用的用法

# Console
goaccess --log-format=COMBINED -f /var/log/apache2/access.log

# 先詢問要怎麼解析 log
goaccess -c -f /var/log/apache2/access.log

# 輸出 HTML (特定版本以後才有)
goaccess --log-format=COMBINED -f /var/log/apache2/access.log -o report.html

# 輸出 realtime HTML (特定版本以後才有)
goaccess --log-format=COMBINED -f /var/log/apache2/access.log --real-time-html -o report.htm

有多個 log (含 .gz) 的情況,可以參考 https://github.com/allinurl/goaccess/issues/600

# 先解析並存到 db
zcat /var/log/nginx/access.log*gz | goaccess -p /etc/goaccess.conf -a -o /dev/null --keep-db-files
# 從 db 載入資料,並且解析最新的 access.log
goaccess -p /etc/goaccess.conf -f /var/log/nginx/access.log --real-time-html -a -o /usr/share/nginx/html/goaccess.html --load-from-disk

Automatically generate GoAccess stats 的處理更費工,還放到 git 去,我覺得蠻值得研究的。我只大略看一下,後來沒用。

Vagrantfile 依版本給設定

上個月因為 vagrant 升級,在 Vagrantfile 裡加了 vb.default_nic_type = “virtio”,但今天同事使用 vagrant up 時,出現錯誤。原來我同事使用的是 vagrant 2.1,而我已經用 vagrant 2.2 了。

之前知道 Vagrantfile 其實是 ruby 語言,因此知道可以在裏面寫程式來處理,在網路上找看看怎麼做,就找到了。關鍵就是利用 Vagrant::VERSION 這個變數。

如果要印出訊息,就直接用 puts ,在執行 vagrant status 等指令時,就會看到。在找這個時,意外看到 vagrant 有 message 系統 (print message after booting vagrant machine with “vagrant up”),可以在指定的情況輸出訊息:

config.vm.post_up_message = "This is the start up message!"

tldr

tldr = too long don’t read

覺得 man 太冗長,懶得看嗎?試試 tldr,這指令直接給你常用的範例跟簡短的說明。
tldr 專案網址:https://github.com/tldr-pages/tldr
有各種語言的客戶端,用 bash 版的是最方便的了 (適用於 zsh/bash/csh/ksh…..):https://github.com/raylee/tldr

安裝很簡單,用 curl 下載,放到 PATH ,收工。

# 下載到 ~/bin,然後確定 ~/bin 有在 PATH 裡
curl -o ~/bin/tldr https://raw.githubusercontent.com/raylee/tldr/master/tldr
# 設定自動完成
complete -W "$(tldr 2>/dev/null --list)" tldr