typescript 的 dirname/basename

node 是有一個 path 的 package,但這個 package 會依賴 process 來取得平台環境,以決定要用 win32 或是 posix 來處理路徑。

但我其實只是要簡單的取得父路徑跟從路徑取出檔案或目錄名稱,不需要這樣麻煩。上網找到這篇:Javascript functions for basename and dirname 。它的實作是使用 regular expression 來處理,所以傳回的並不是單純的字串,而是一個陣列 RegExMatchArray 。參考 MDN 的 String.prototype.match() 來做調整,簡單的說,陣列的第一個元素就是處理的結果,所以只要先判斷傳回值是否為  null ,然後再傳回第一個元素即可。

// Typescript
/**
 * 取得父路徑
 */
export function dirname(path: string): string {
  let newPath = '';
  // 找符合 '/aaa/bbb/ccc/' 的字串
  const regExMatchArray = path.match(/.*\//);
  // 沒有找到,傳回 '/'
  if (regExMatchArray === null ) {
    newPath = '/';
  }
  else {
    // 有找到
    newPath = regExMatchArray[0];
    // 看最後字元是否為 '/',是的話,就移除。
    if (newPath.endsWith('/')) {
      newPath = newPath.substring(0, newPath.length - 1);
    }
    // 最後結果的長度為0,加上 '/'
    if (newPath.length === 0) {
      newPath = '/';
    }
  }
  return newPath;
}

/**
 * 取得檔名或目錄名
 */
export function basename(path: string): string {
  // 把 '/' (含)之前的字元都替換成空字串
  return path.replace(/.*\//, '');
}

如何在 systemd 裡啟用 rc.local

以前用 sysv 或 upstart 時,很方便,想要在開機時跑一些指令,又懶得寫啟動 sysv init script 或 upstart job 時,就寫在 rc.local 裡就好。現在幾乎各大 Linux 發行版本都改用 systemd 了,那 systemd 又該怎麼做呢?印象中之前查過兩三次了,這次再查,決定還是記錄一下好了。

主要參考這篇:How to Enable /etc/rc.local with Systemd – LinuxBabe

第一步,新增 /etc/rc.local ,然後把要執行的指令放到裡面去,並且用 chmod +x /etc/rc.local 加上執行權限。

第二步,新增 /etc/systemd/system/rc-local.service

[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99

[Install]
WantedBy=multi-user.target

第三步,啟用這個服務

sudo systemctl enable rc-local

硬碟空間不足?用OverlayFS來整合新硬碟空間

想到昨天還前天朋友問的,說伺服器的硬碟空間沒了,買了新的硬碟來用,有沒有辦法用一個比較便利的方法來掛載使用。我那時回答是說,得掛載到新的資料夾,再使用 symbolic link 方式去處理,今天看到 overlayfs,覺得應該可以用,就研究了一下。

主要是看了這三篇

第一篇側重於原理,第二篇很簡單,我覺得第三篇比較清楚。

是這樣的,本來看完第一篇跟第二篇,在嘗試的時候 (我是用 dd 做磁碟映像來掛載),一直遇到 wrong fs type, bad option, bad superblock on overlay 的問題,掛載不起來。看完第三篇,才知道自己錯在哪裡,就是 upperdir 必須要跟 workdir 在同個磁碟上,這樣掛載才不會有問題。

下面就開始實作,建立 olddisk,這裡把它當作是舊的 /home

dd if=/dev/zero of=olddisk bs=1024 count=1024
mkfs.ext4 olddisk

如果是真實情況的話,那麼這原本是掛載到 /home,這裡就把它改掛載到 /mnt/home。

sudo mkdir -p /mnt/home
sudo mount olddisk /mnt/home
sudo chown -R $USER:$USER /mnt/home

建立使用者目錄,盡可能模擬真實狀況,在真實狀況下,這步驟不用做

mkdir -p /mnt/home/user{1,2,3,4,5}

然後重新掛載為唯讀,模擬為以後都不去動的狀態

sudo mount -o remount,ro /mnt/home

建立 newdisk ,也就是模擬為新的硬碟

dd if=/dev/zero of=newdisk bs=1024 count=8192
mkfs.ext4 newdisk

掛載到 /mnt/newdisk

sudo mkdir -p /mnt/newdisk
sudo mount newdisk /mnt/newdisk
sudo chown -R $USER:$USER /mnt/newdisk

在新磁碟上建立兩個目錄,一個 home,一個 workdir。home 是 upperdir,workdir 還是 workdir,至於什麼是 upperdir,什麼是 workdir ,這裡就不多做說明了。

mkdir -p /mnt/newdisk/{home,workdir}

好,開始來掛載 overlay,這裡是掛載到 /home1,實際狀況會是 /home

sudo mount -t overlay none -o lowerdir=/mnt/home,upperdir=/mnt/newdisk/home,workdir=/mnt/newdisk/workdir /home1

看看 /home1

ls /home1
# 結果:
# lost+found  user1  user2  user3  user4  user5

建立新的使用者資料夾看看

mkdir -p /home1/user{6,7,8,9,10}

再來看看 /home1 有什麼變化

ls /home1
# 結果:
# lost+found  user1  user10  user2  user3  user4  user5  user6  user7  user8  user9

這時可以看到有確實的增加了 user6, user7, user8, user9, user10 這些資料夾,然後來看看新的硬碟裡怎麼樣了

ls /mnt/newdisk/home
# 結果:
# user10  user6  user7  user8  user9

這時可以看到新的使用者資料夾在這邊了,那 workdir 呢?

ls /mnt/newdisk/workdir
# 結果:
# work 

會發現只有 work,看來這是 kernel 工作用的目錄,可以忽略。那如果去原來在舊磁碟的使用者資料夾裡新增或修改檔案,會怎麼樣呢?

cd /home1/user1
touch {x,y}.md
cd /home1/user2
touch z.md

看舊磁碟上有沒有變化

ls /mnt/home/user1
# 結果:
#

會發現一樣是空的。來看看新磁碟

ls /mnt/newdisk/home/user1
# 結果:
# x.md  y.md

至此,存取一樣都在 /home1,但新的資料都會被放在新磁碟上了。

整理一下,在實際情況時的處置

  1. 接上新硬碟,分割、格式化好之後,掛載到 /mnt/newdisk ,建立兩個資料夾:home, workdir
  2. 如果 /home 是在分割區的話,先卸載,改掛載到 /oldhome;如果是跟 / 在一起的話,改個名字,例如 /oldhome
  3. 掛載:sudo mount -t overlay none -o lowerdir=/oldhome,upperdir=/mnt/newdisk/home,workdir=/mnt/newdisk/workdir /home
  4. 修改 /etc/fstab ,這樣下次開機時,才會生效。修改重點有三,一是原來的 /home,二是掛載新的磁碟,三是加入 overlay 的處理。

Macbook 的 Touchbar 與 ESC

前幾天用 android studio 的 vim mode 打字打到一半,發現 Touchbar 上的 ESC 不見了,靠北,啊這樣是要怎麼打字打下去? 找了一下,在 macos – Esc button from touchbar has disappeared – Ask Different 找到解法,用

sudo pkill TouchBarServer

就可以找回失落的 ESC

在那個時間點,有上推特分享,推友跟我分享了不少方法:

  • 按 Ctrl + [ ,這個就等於是 ESC
  • 按 Command + ~
  • 用虛擬鍵盤
  • 按 Ctrl + C
  • 外接鍵盤
  • 把 jj 對應為 ESC

有點不好意思的是,這些我都還沒試過,先記下來,以免日後再次遇到。

電影流水帳(2020/06/01~2020/06/10)

Carrie Fisher aka Princess Leia figure at Madame Tussauds London
Carrie Frances Fisher 飾演星際大戰裡的莉亞公主
  • Star Wars: The Rise of Skywalker (IMDB, Wikipedia),台譯:星際大戰九部曲:天行者的崛起。
  • Rambo: Last Blood (IMDB, Wikipedia),台譯:藍波:最後一滴血。

Star Wars: The Rise of Skywalker

每次看沒有中文字幕的,總是會覺得少了一點什麼,我想是英文的聽讀還不夠強的緣故吧。

這集主要的故事線是 Rey 的身世。Ben Solo 找到了 Palpatine ,加入了西斯,但他始終知道,自己只是被利用,對於這整個銀河他有另外的想法。Rey 隨著原力的指引,身世的部份慢慢有了線索,後來跟 Ben Solo 碰面之後,Ben 告訴她,她就是 Palpatine 的孫女,並且告訴她,我們一起聯手統治銀河吧。打了一場,Ben Solo 受到母親原力影響,被 Rey 刺了一劍,但 Rey 相信他有善良的一面,以原力救活了 Ben。Rey 很害怕自己加入邪惡的一方,就跑去躲了起來,而 Ben 卻因此變為善良。

之後,反抗軍跟西斯軍展開戰鬥。Rey 則是在絕地英靈的啟迪下,知道了能定義自己的,不是血統,而是自己的選擇,於是前往尋找 Palpatine 。遇到 Palpatine 以後,她拒絕了 Palpatine 的提議,跟 Palpatine 打了起來。Ben 這時也趕到,跟 Rey 一起對抗 Palpatine。果然薑是老的辣,Palpatine 汲取了他們兩人的原力,讓自己恢復到最強大的狀態,眼看 Rey 跟 Ben 就要輸了。就在這個時候,絕地英靈幫 Rey 開了外掛,一個反擊,將 Palpatine 打過來的閃電反彈回去,消滅了 Palpatine。Rey 這時氣力放盡,就要掛了。重傷的 Ben 這時將自身僅存的原力傳給了 Rey,算是報恩吧,然後自己面對了死亡。

抵抗軍跟 Rey 雙雙告捷,西斯軍被打敗,宇宙再也沒有邪惡勢力。

Rambo: Last Blood

有一點點 Old Man Logan 的味道,藍波歷經了人生了波折,回到家鄉,只想好好過後半生的藍波,卻因為Garbrielle,決定重新拿起之前的專業來復仇。我覺得很中規中矩,有點讓人惆悵,也能讓人感受到藍波最後的那種心情。

藍波經歷幾次任務以後,心裡是百感交集,對美國與人生失去了希望,回到出生地以後,他看到了可愛的Gabrielle,跟她生活了一陣子以後,他開始慢慢對人生恢復了信心。Gabrielle長大以後,她的朋友告訴她有Gabrielle生父的消息,於是Gabrielle不聽祖母與藍波的勸,冒險越過墨西哥國境去找生父。

意外就這樣發生了,Garbrielle被壞人帶走,強迫賣淫並注射毒品讓她成癮。藍波去找人,輾轉找到,殺進妓院,跟壞人打了一陣,救出了奄奄一息的Garbrielle。可惜Garbrielle沒能順利回到家,在回家的路上,她就已經走了。藍波很難過,非常非常難過,帶她回去見Garbrielle的祖母,祖母也是非常難過。埋了Garbrielle以後,藍波超不爽的,先送走Garbrielle的祖母,然後開始佈署陷阱,做迎敵的準備。透過當地朋友的幫忙,去挑釁壞人,讓對方殺到自家農場來。

怒氣沖沖的壞人殺到家門來了,藍波利用之前佈下的陷阱,打起自己最擅長的地道游擊戰,殲滅了壞人,為Garbrielle報仇,也是為當地除了一個禍害。

gitlab 看不到 last commit 跟 last updated 問題

gitlab 升級到 13.0.5 以後,發現有這問題,原本以為是 gitlab-ce 問題,下次升級就解決了。但是今天升級到 13.0.6 以後,並沒有解決。 利用瀏覽器的開發者工具去查看,發現有個請求是回傳 404,仔細看他網址裡,有 %2F

https://host/user/gitlab-ce-commit-info-bug/-/refs/master/logs_tree/folder_1%2Ffolder_2?format=json&offset=0

手動把 %2F 改為 / 以後,就可以拿到資料。

利用 “gitlab-ce “refs/master” “%2F” 404gitlab-ce “refs/master” “%2F” 404” 這幾個關鍵字在 gitlab issue 209941 找到線索,是 Apache 問題。

Apache 要在 virtualhost 裡加上 AllowEncodedSlashes NoDecode

但我這樣試了以後,發現還是不行。後來看了 Apache 文件,知道除了 NoDecode 之外,還可以設定為 On:AllowEncodedSlashes On 

於是這樣就可以成功顯示了。

但是為了安全性問題 (Apache 文件不建議這樣設定),再去找了一下,看為什麼會這樣。
後來在 StackOverflow 上找到解答,除了要改 AllowEncodedSlashes 之外,還要改 mod_proxy ProxyPass ,在後面加上 nocanon 即可。

範例

AllowEncodedSlashes NoDecode
<Location /example/>
  ProxyPass http://anotherserver:8080/example/ nocanon
</Location>

電影流水帳(2020/05/11~2020/05/31)

Q'Orianka
Q’orianka Kilcher 飾演 Dora and the Lost City of Gold 裡守護黃金城的公主。
  • Secret Superstar (IMDB, Wikipedia),台譯:隱藏的大明星。
  • Dora and the Lost City of Gold (IMDB, Wikipedia),台譯:朵拉與失落的黃金城。

Secret Superstart

早上吃早餐時,轉到Fox Movie,剛好「隱藏的大明星」剩下30分鐘。茵希雅去了孟買,跟沙克帝在告別,沙克帝跟她說,我雖然每次被提名都沒得獎,但像你這樣的才華,就跟汽水裡的泡泡一樣,是會自己浮上去的,會慢慢的發光發熱。沒多久,場景帶到茵希雅家裡,茵希雅跟媽媽說,我去了孟買找了沙克帝,我覺得你應該要離婚,我可以靠唱歌來養你跟弟弟。媽媽很驚訝也有點生氣,告訴他你怎麼可以自己去孟買,回來還叫我離婚。對,茵希雅長期受到丈夫的暴力對待,兒女都看不下去。這場爭執在母親斥責女兒後結束,茵希雅跑回房間去,這時奶奶走了過來,跟茵希雅說了她媽媽當時懷她的事情。本來在知道懷的是女兒以後,是決定要墮胎的,但是茵希雅的媽媽逃走躲起來,到了十個月後才抱著孩子回來求情說,下次一定會生個男生的,現在孩子也生下來了,我們就撫養她吧。

茵希雅這時才知道當初媽媽並不是她所想的那樣懦弱,而是鼓了很大的勇氣逃走,才生下她。於是她放下對媽媽的怨,配合媽媽一起準備搬家的東西,再過一陣子全家跟父親一起去沙烏地阿拉伯工作。電視上一直在播報著「隱藏的大明星」的報導,這個女孩蒙著面,彈著吉他唱歌的影片透過Youtube頻道在全國各地走紅,但是沒有人知道她是誰,只有她的好友跟沙克帝知道。但電視上一直在播放著,媽媽也或多或少猜到了,她沒有多說什麼,只是看著最近女兒落寞的神情,也想著自己的處境,心疼,但是好像也不能做些什麼。在茵希雅學期結束後,一家人前往機場搭飛機,在排隊辦理登機程序,快輪到他們到櫃檯時,父親內急去上了廁所。就輪到他們了,可是媽媽不知所措,櫃檯人員本來要他們先讓後面的辦理,但茵希雅挺身而出,成熟的跟櫃檯人員應對,辦完手續。

上了飛機,茵希雅的位子上有人佔了她的位子,茵希雅婉轉的告知,並請他移座。在一旁的媽媽看到自己的女兒,深深的覺得自己女兒已經長大,可以成熟的應對了。到了孟買轉機,要託運行李,父親不願意多付吉他託運的錢。媽媽冷靜的跟父親說明,這是女兒的夢想,請他也一起託運,但是父親不肯,還威嚇她。接下來的一幕,讓我眼眶含著眼淚看完。媽媽不退縮,再次說明自己的立場,父親還是不願意,媽媽這時拿出了文件簽名,然後告知了自己女兒的事情,以及自己等一下要怎麼做。簡單的說,你如果動手打我,這裡有攝影機,而且你這樣做也會影響到你工作。我們婚姻就走到這裡,你就帶著你媽去沙烏地阿拉伯吧,等你回來,我們再來談後續的事情。說完,媽媽就帶著茵希雅跟弟弟走了。

後續,他們去參加了頒獎典禮,茵希雅得到了獎項,在台上發表了感人的演說。大概就這樣吧,很感人的故事,仔細想想,我碰到這種母愛、父愛的故事都很容易留下眼淚。

Dora and the Lost City of Gold

我覺得導演跟編劇的安排很好,直接把 Dora 拉到國高中的年紀,這樣可以讓演員的年紀不會那麼突兀。同時,也設定讓 Dora 從小在叢林長大,到了國高中才到城市裡唸書,讓小女孩經歷青少年對於交友的困擾,也讓 Dora 除了長大之外,還保有純真的一面。

故事蠻簡單的,看了前面 30 分鐘,大致上可以猜到後面的劇情。Dora 從小在叢林長大,受到父母的薰陶,對於冒險這件事情非常有興趣。表哥 Diego 小時候也是住在叢林,但並沒有住很久,之後就搬去城市唸書了。Dora 的父母接受了委託,要去調查事情,而 Dora 則被送到表哥所在的城市去唸書。Dora 在學校裡算是一個怪咖,不是很受歡迎,表哥 Diego 則對此感到困擾。某天校外教學,Dora 跟表哥以及其他兩個同學被湊成一組,然後就被壞人捉走了。壞人是為了黃金城而來的,他們想要挾持 Dora ,威脅 Dora 父母帶他們去找黃金城。Dora 跟其他三人被帶到叢林裡,被一個自稱是 Dora 父母朋友的教授救了,5個人就在叢林裡探險尋找黃金城。經過冒險的橋段之後,原來那個自稱是 Dora 父母朋友的教授就是壞人,利用好警察、壞警察的手法,設計 Dora 帶他們去找到黃金城。可是,Dora 也不是笨蛋,早就留了一手,讓壞人掉入陷阱,被叢林守護者捉住。最後,黃金城是找到了,可是也因為觸發機關的關係而被封住了。

整個故事就是很有家庭歡樂的氣氛,蠻適合陪孩子一起看的。

iperf3 測試網路速度

閱讀 指令式的網路速度測試工具 iPerf3 ,揪出網路頻寬真實的一面 以後做的小摘錄。

簡單說用法,因為是要測試內部網路的網路速度,所以要兩台電腦。一台執行

iperf3 -s

一台執行

iperf3 -c <server_ip>

這樣就可以了。也有公用的伺服器可以測,這樣就要一台電腦就行 (用 ipef3 -c <server_ip>),亞洲區只有兩台,一台在中亞(哈薩克),一台在印尼,要注意,使用公用伺服器的話,測出來的速度並不是網路內部電腦間的速度,而是電腦到Router到外部伺服器的速度。

flutter stable/beta 並存

簡單說,有專案因為怕被影響到,只想用 stable 來建置,不想用 beta,可是又想要試驗 flutter web ,而 flutter web 又只有 beta channel 才有,所以想讓他們並存。

其實意外的簡單,就只是放在不同目錄,只要在使用的時候小心,不要用到不對的 flutter 就行,在 terminal 直接下指令的話,會需要特別注意。

# 切到你要放 flutter beta channel 的資料夾
git clone https://github.com/flutter/flutter.git flutter-beta -b beta
cd flutter-beta/bin
./flutter precache
./flutter config —enable-web
./flutter devices

在 Android Studio 建立 flutter project 時,會問 flutter SDK 路徑,把路徑指到剛剛放 flutter beta channel 的位置,就可以了。

Visual Studio Code 的話,需要改 workspace preferences ,改裡面的 dart.flutterSdkPath (來源1 / 來源2 )

"settings": {
"dart.flutterSdkPath": "/Users/youruser/flutter-beta"
}

直接用指令的話,就要確定 PATH 是對的,這時候可以預先寫好環境變數檔案,然後用 source 來處理

# flutter-stable.env
export PATH=/Users/youruser/flutter-stable:$PATH
# flutter-beta.env
export PATH=/Users/youruser/flutter-beta:$PATH
# 切換到 stable
source flutter-stable.env

# 切換到 beta
source flutter-beta.env

紀錄一下 MacOS 的中文輸入法

之前有找過一次了,今天又再找一次,這次把找的過程記錄下來。那這次為什麼要找呢?是因為小麥注音輸入法不知道為什麼當機終止了,選不到這個輸入法,想說找穩定的輸入法來使用。

之前換小麥注音輸入法的主因是因為我實在是無法適應 MacOS 的內建注音輸入法,用了一陣子還是無法適應,特別是打注音符號,就斷然放棄。

言歸正傳,目前可以找到的幾個:

  1. 小麥注音
  2. Yahoo!奇摩注音輸入法
  3. 超注音
  4. 香草輸入法 (沒有注音)
  5. 自然注音輸入法
  6. 鼠鬚管

小麥注音

用 homebrew 就可以安裝:brew install mcbopomofo

目前免費,沒有智慧選字,也沒有詞庫,按 shift+, 可以輸入全形標點符號。 網址:https://github.com/openvanilla/McBopomofo

Yahoo!奇摩注音輸入法

安裝需要手動,homebrew 以前有這個 cask,但是後來被移出去了。

目前免費,有智慧選字,輸入法程式沒有持續更新,Yahoo 已經將這整個輸入法開放原始碼了,安裝包是 zonble 大大熱心去編譯並打包的 (zonble大大就是OpenVilla香草輸入法/小麥注音輸入法的開發者)。 網址:https://github.com/zonble/ykk_installer/

按 shift+, 可以輸入全形標點符號

介紹:

超注音

安裝要繞個路,透過 Google Play,我猜想這是開發者要收費的緣故。價格:500 NTD

安裝方法:

  1. 使用 Android 手機,去 Google play 安裝 (超注音 for macOS)
  2. 開啟 app,裡面有操作說明,簡單的說,這包 apk 裡面有超注音的安裝程式,你要依照操作說明把這個安裝程式放到你的 macos 機器上,然後安裝。

網址:https://www.superkbd.com/

參考資料:超注音 for macOS 開放下載!為 Mac 再添一款輸入法

香草輸入法

安裝:brew install openvanilla

如果你需要倉頡、簡易(速成)、大易、行列、符號與日文假名、粵拼等輸入法,裝這個就對了,不過我沒用過。

網址:https://openvanilla.org/

自然注音輸入法

老牌的輸入法,要上官方網站購買,網址:https://www.goingpro.me/products

價格 2000 NTD,如果你有雙系統需求,可以考慮購買 Win+Mac 共通版,價格 3500 NTD,可以安裝在三台電腦上。

鼠鬚管

感謝推友 Ralphsun73221 的推薦。鼠鬚管就是只有注音的 RIME (Linux版是中州韻,Windows 版是小狼毫)。

安裝:brew cask install squirrel

介紹:【RIME 鼠鬚管注音版】Mac 中最好用的注音輸入法!

最終的選擇

之前是使用小麥注音輸入法,這個先保留,不移除。現在則是安裝了 Yahoo!奇摩注音輸入法來試用看看,未來如果不好用,再來考慮安裝鼠鬚管或是購買超注音或是購買自然注音輸入法。

剛剛使用,注意到一點,選字的游標位置不太一樣:

  • 小麥注音輸入法跟內建的注音輸入法,選字是選前個位置的字。
  • Windows/Linux 上的輸入法跟Yahoo!奇摩注音輸入法,選字是選後面位置的字。