Ming's blog

一個軟體工程師的旅程 :)

用了 3 年多的 LinuxMint 前陣子宣佈 LinuxMint 18.3 是 KDE edition 最後一個版本,然後 .. 就沒有然後了 T_T

索性昨天把系統重新裝成 Kubuntu 18.04 (真心很喜歡 KDE Plasma),不得不說重裝 Unix-like 系統感覺真的超好,重裝 / 保留 /home 的情況,Firefox / Chrome / Opera 全部都不需要重新設定 (設定檔保留於 /home)。

不過裝完 vim 8 之後,遇到一個很大的問題,一直在使用的 vim-copycat(georgefs/vim-copycat)

E319: Sorry, the command isn’t available in this version: python

vim-copycat(georgefs/vim-copycat) 是用於同步系統跟 vim 的剪貼板 (clipboard)

輸入指令:

1
~$ vim --version | grep python

顯示:

1
2
+comments          +libcall           -python            +vreplace
+conceal +linebreak +python3 +wildignore

在 Kubuntu 18.04 使用 apt-get 安裝 Ubuntu repository 中的 vim 已經拿掉了 Python 2 的支援,導致 .vim/bundle/vim-copycat/plugin/copycat.vim 使用 Python 2 出現問題

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
Error detected while processing /home/ming/.vim/bundle/vim-copycat/plugin/copycat.vim:
line 23:
E319: Sorry, the command is not available in this version: python << EOF
line 24:
E492: Not an editor command: import sys
line 25:
E492: Not an editor command: import vim
line 26:
E492: Not an editor command: sys.path.append(vim.eval('expand("<sfile>:p:h:h")'))
line 27:
E492: Not an editor command: import copycat_plugin
line 28:
E492: Not an editor command: EOF

我決定採用解決方式是將 Python 2 的代碼改成 Python 3,下面將一步一步紀錄這個過程。

事前準備:

1
2
sudo pip3 install copycat-clipboard
sudo apt-get install xclip

首先最直觀的根據錯誤紀錄將 .vim/bundle/vim-copycat/plugin/copycat.vim 中的 python 全部取代為 python 3

1
\:1,$ s/python/python3/g

儲存之後,接下來打開 vim 錯誤變成:

1
2
3
4
5
6
7
8
9
10
Error detected while processing /home/ming/.vim/bundle/vim-copycat/plugin/copycat.vim:
line 28:
Traceback (most recent call last):
File "<string>", line 4, in <module>
File "/home/ming/.vim/bundle/vim-copycat/copycat_plugin.py", line 11, in <module>
import copycat
File "/usr/local/lib/python3.6/dist-packages/copycat.py", line 73
print 'no reg {}'.format(name)
^
SyntaxError: invalid syntax

很明顯是 Python 2 的 print 用法,解決的方法很簡單,將所有 copycat.py 中的 print “” 改成 print(“”)

1
:1,$ s/python/python3/g

接下來錯誤變成

1
2
3
4
5
6
7
8
9
10
11
12
13
Error detected while processing function <SNR>36_push_into_clip:                                                                                                                                
line 4:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/ming/.vim/bundle/vim-copycat/copycat_plugin.py", line 37, in deco
result = func(*args, **kwargs)
File "/home/ming/.vim/bundle/vim-copycat/copycat_plugin.py", line 53, in copy
copycat.copy(name=name, value=value)
File "/usr/local/lib/python3.6/dist-packages/copycat.py", line 96, in copy
value = smart_str(value)
File "/usr/local/lib/python3.6/dist-packages/copycat.py", line 20, in smart_str
if not isinstance(s, basestring):
NameError: name 'basestring' is not defined

一樣是 copycat.py,將 copycat.py 中的 smart_str 函數改為:

1
2
3
4
5
6
7
8
9
19 def smart_str(s, encoding='utf-8', errors='strict'):
20 #if not isinstance(s, basestring):
21 # s = str(s)
22 #elif isinstance(s, unicode):
23 # return s.encode(encoding, errors)
24 #elif s and encoding != 'utf-8':
25 # return s.decode('utf-8', errors).encode(encoding, errors)
26 #else:
27 return s

錯誤變成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Error detected while processing function <SNR>36_push_into_clip:                                                                                                                                
line 4:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/ming/.vim/bundle/vim-copycat/copycat_plugin.py", line 37, in deco
result = func(*args, **kwargs)
File "/home/ming/.vim/bundle/vim-copycat/copycat_plugin.py", line 53, in copy
copycat.copy(name=name, value=value)
File "/usr/local/lib/python3.6/dist-packages/copycat.py", line 100, in copy
clipboard.copy(value)
File "/usr/local/lib/python3.6/dist-packages/clipboard.py", line 31, in copy
pipe.communicate(text)
File "/usr/lib/python3.6/subprocess.py", line 828, in communicate
self._stdin_write(input)
File "/usr/lib/python3.6/subprocess.py", line 781, in _stdin_write
self.stdin.write(input)
TypeError: a bytes-like object is required, not 'str'

將 copycat.py 中的 copy 函數改成:

1
2
3
4
5
6
7
8
def copy(value=None, name=None):
value = value or not sys.stdin.isatty() and sys.stdin.read()

#value = smart_str(value)
with Storage() as storage:
storage.save(value, name=name)
if not name:
clipboard.copy(value.encode('utf-8'))

copy 函數正常後,現在已經可以正常複製,接下來 paste 錯誤訊息:

1
2
3
4
5
6
7
8
9
10
11
12
Error detected while processing function <SNR>36_pop_from_clip:                                                                                                                                 
line 3:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/ming/.vim/bundle/vim-copycat/copycat_plugin.py", line 39, in deco
set_to_vim(result_reg, result)
File "/home/ming/.vim/bundle/vim-copycat/copycat_plugin.py", line 25, in set_to_vim
if not isinstance(name, basestring):
NameError: name 'basestring' is not defined
line 4:
E121: Undefined variable: l:result
E15: Invalid expression: l:result

將 copycat.py 中的 paste 函數修改為:

1
2
3
4
5
6
7
8
9
def paste(name=None):
with Storage() as storage:
if not name:
data = clipboard.paste() or storage.get()
else:
data = storage.get(name)
#data = smart_str(data)
clipboard.copy(data)
return data

打開 copycat_plugin.py 將 set_to_vim 函數改成:

1
2
3
4
5
6
7
8
9
10
def set_to_vim(name, value):
#if not isinstance(name, basestring):
# return False

#if isinstance(value, basestring):
value = re.sub(r'([\"\\])', r'\\\1', value.decode('utf-8'))
vim.command('let {}=\"{}\"'.format(name, value))
return True
#return False

完成!

取之於開源,回饋於開源

如果不想要手動改的話,可以參考:

https://github.com/iwdmb/vim-copycat
https://github.com/iwdmb/copycat

我 fork 了 vim-copycat and copycat(copycat-clipboard) 使其支援 Python 3 : )

copycat-clipboard3 pypi repository url:https://pypi.org/project/copycat-clipboard3/

// 這篇還沒寫完

sort.Ints, sort.Strings, sort.Float64s
sort.SearchInts
sort.SearchStrings
sort.SearchFloat64s

背後是 Binary Search。

int(uint(i+j) >> 1

n == len(slice), f 有點類似 C++ STL std::find_if 的 Predicate。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func Search(n int, f func(int) bool) int {
// Define f(-1) == false and f(n) == true.
// Invariant: f(i-1) == false, f(j) == true.
i, j := 0, n
for i < j {
h := int(uint(i+j) >> 1) // avoid overflow when computing h
// i ≤ h < j
if !f(h) {
i = h + 1 // preserves f(i-1) == false
} else {
j = h // preserves f(j) == true
}
}
// i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
return i
}
1
2
3
func SearchInts(a []int, x int) int {
return Search(len(a), func(i int) bool { return a[i] >= x })
}

我的 VSCode 是使用免安裝的 Visual Studio Code Portable 版本,以往如果要更新到最新版本都要手動官方下載、解壓縮,一次兩次還好次數一多就覺得應該更有效率的完成這件事情,後來寫了一段 bash script 自動完成這件事情。

思路其實很簡單,由於 VSCode 的設定、插件 .. 等都會在 ~/.vscode 中,所以可以直接移除掉 Portable 的所有檔案,並且下載最新版本移動過去。

有時間可以加上初步比對版本,比較 /VSCode-linux-x64/resources/app/package.json 以及 https://github.com/Microsoft/vscode/releases 的 latest releases 資訊去判斷是否要更新。

vscodePath 是 Visual Studio Code 的路徑。

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

vscodePath="/home/ming/Programs/VSCode-linux-x64"

if [ -d "$vscodePath" ]; then
rm -rf $vscodePath/*
else
mkdir -P $vscodePath
fi

wget -q -O - https://go.microsoft.com/fwlink/?LinkID=620884 | tar xz -C /tmp
mv /tmp/VSCode-linux-x64/* $vscodePath

從高三開始用 Vim 至今也蠻多年的時間了,當初會開始使用 Vim 大概是因為看到一句讓我心動的話:學一次快捷鍵到哪個編輯軟體都適用。

後來確實使用了不少其它編輯軟體、IDE (Atom, Sublime, VSCode, IDEA),都可以找到 Vim plugin,不需要再重新適應每套軟體各自的快捷鍵。

這篇文章紀錄一下一些 Vim 使用過程中的小 tips,幫助自己快速查閱。

Paste multiple lines

eg. 重複貼 30 行 30p

需要在 VISUAL LINE model 使用

Find and Replace all

1,$ s/old/new/g

Plugin: tpope/vim-surround

csw" Hello world! -> “Hello” world!
yss" Hello, world! -> “Hello, world!”

Plugin: scrooloose/nerdcommenter

<leader>cc 加注释
<leader>cu 解开注释

<leader>c<space> 加上/解开注释, 智能判断
<leader>cy 先复制, 再注解(p可以进行黏贴)

Reference

vim Cheat sheet

Vim

Plugin

Tutorial

這篇文章是躺在我的 Evernote 很長一段時間的筆記。

會有這篇筆記是因為從國小開始就常常需要幫別人安裝、重灌 Windows 系統,每次都要重新思考需要幫對方安裝哪些軟體,而且很容易就有疏漏因而有了這篇筆記,算是一份 SOP 吧,文章列的軟體基本上是安裝系統必備。

Software

  • 7-Zip
  • Chrome
    • uBlock Origin
  • Internet Explorer 11 (Windows 7)
    • x86 | x64
  • IObit Driver Booster (交情夠好的話會手動幫忙找驅動)
  • .NET Framework 4 (Windows 7)
  • TeamViewer or AnyDesk
  • Microsoft Office 2013+
  • Microsoft Office 輸入法 2010 (Windows 7)
  • PotPlayer
  • Notepad++
  • Adobe Acrobat Reader DC or PDF-XChange Viewer

Antivirus

Windows 10

  • Windows Defender

Windows 7

  • Avast Free Antivirus
  • Microsoft Security Essentials
  • Kaspersky Free Anti-virus

Other

  • LINE

  • Raidcall

  • Skype

  • Garena Platform

  • Twitch Curse

最近打算把舊的 blog 從 lovein.tw 移出,選了 RedHat 的 SaaS 平臺 OpenShift Online 2。

重要的兩個 repository

OpenShift Cartridge for Nginx and PHP 7

pinodex/openshift-cartridge-nginx-php7

Custom cartridge for OpenShift providing MySQL 5.7.17

icflorescu/openshift-cartridge-mysql

Add Application ... -> Search by keyword or tag 輸入 openshift-cartridge-nginx-php7

完成之後,進入 application overview 畫面,選 Or, see the entire list of cartridges you can add

Install your own cartridge 中輸入 https://raw.githubusercontent.com/icflorescu/openshift-cartridge-mysql/master/metadata/manifest.yml


取得 MySQL Host IP and Port

1
2
~$ echo $OPENSHIFT_MYSQL_DB_HOST
~$ echo $OPENSHIFT_MYSQL_DB_PORT

取得 PHP IP

1
~$ echo $OPENSHIFT_PHP_IP

設定 MySQL

1
2
3
4
${OPENSHIFT_DATA_DIR}.mysql/bin/mysql --socket=${TMP}mysql.sock -u root
mysql> create database ls_wp;
mysql> GRANT ALL PRIVILEGES ON LS_WP.* TO 'ls_wp'@'**PHP IP**.%' IDENTIFIED BY '**PassWord**' WITH GRANT OPTION;
mysql> flush privileges;
1
2
3
4
5
~$ git clone **Source Code ssh url**
~$ cd **app_name**/www
~$ rm -rf ./*
~$ git add -A
~$ git commit -m "remove template file"
1
2
3
~$ wget -q -O - https://wordpress.org/latest.tar.gz | tar xz && mv ./wordpress/* ./ && rm -rf ./wordpress
~$ git add -A
~$ git commit -m "add wordpress-4.8-zh_TW source code"

如果需要上傳附件,需要修改 client_max_body_size 的大小

1
2
3
4
5
6
7
# Handle any other URI
location / {
#try_files $uri $uri/ =404;
try_files $uri $uri/ /index.php?$args;
}

client_max_body_size 15M;
1
2
~$ git add -A
~$ git commit -m "edit nginx setting"

需要修改 php.ini 設定的話

1
2
~$ cd config/php.d
~$ touch php.ini && vim php.ini

如果需要上傳附件,要修改 PHP upload_max_filesizepost_max_size 的大小(PHP7 預設為 2M),例如要將以前的 WordPress Import。

1
2
upload_max_filesize = 15M
post_max_size = 15M
1
2
~$ git add -A
~$ git commit -m "add php.ini"

完成之後就可以 git push 到 OpenShift 的 repository 上面。

1
~$ git push

接著打開 Application URL 就可以進行 WordPress 安裝。

比較需要注意的是 Database 的設定,位置請填寫下面指令的結果。

1
~$ echo $OPENSHIFT_MYSQL_DB_HOST:$OPENSHIFT_MYSQL_DB_PORT

如果要開啟 WordPress FORCE_SSL_ADMIN

1
2
3
4
~$ vim app-root/repo/www/wp-config.php
define('FORCE_SSL_ADMIN', true);
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS'] = 'on';

Reference

這個 Blog 一直使用 hexo 這個 blog framework(Static Site Generators)

記得之前剛開始使用 hexo 的時候就會遇到一個問題

當標題出現 : [] 冒號跟括號的時候,在 hexo generate 的時候會有問題

直到在 hexo 的 GitHub Issues 中看到了

開這個 issue 的網友有遇到一樣的問題

Hexo uses directly js-yaml (after some tabulator escaping).

var yaml = require(‘js-yaml’),
escape = require(‘../../util’).escape.yaml;

module.exports = function(data){
return yaml.load(escape(data.text));
};
In my eyes, you have two choices:

a) use quotation marks, as in title: “my title : with colon” to simply escape the title. There are some more to find in the YAML specs

b) extend the js-yaml library

You wrote “He tried escaping the colon within the title, but doing so had no effect.”… hmm what exactly have you tried? For me option a) worked in a quick test. Following the specs “title: my title : with colon” should work, too, but I didn’t test this one.

sergiolepore 提到:

Use quotation marks. Take a look at this:

post.md
Rendered post

最近在學校管的某系的 DNS Server 掛掉了,ssh 連不上去,ESXi 也無法對其重開機。

透過 ESXi 直接開啟(不透過 ssh),發現一直卡在 initramfs

直接 reboot 沒有用,重新開機還是會直接進到 initramfs,

仔細看一下錯誤訊息,其中

1
/dev/sda1: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.

還好進入 initramfs 模式中還有 busybox-initramfs 可以使用

可以透過 fsck (file system consistency check) 指令

1
fsck -y */dev/sda1*

針對檔案系統進行修復,reboot 之後就正常了。

0%