電影流水帳(2020/06/11~2020/06/20)

Sigourney Weaver

Galaxy Quest

之前有看電影神搜的介紹,再加上有喜愛的石內卜 (Alan Rickman) 跟 Sigourney Weaver 演出,再加上又剛好在 HBO 看到,就順著從中間的地方看完了。

故事就一群演影集的演員被外星人捉走,那外星人為什麼捉他們,原因很簡單,因為他們演的影集就是講太空冒險故事的。外星人看了他們演的影集,以為他們就是真的星際艦隊,有能力、有勇氣,可以幫助他們對抗壞蛋。演員們在知道這種情況之後,知道外星人誤會他們了,可是外星人又非常仰慕他們,只好不上不下的配合著演下去。只是事情這樣下去不行,早晚會被外星人知道他們只是個演員。在受到壞蛋外星人持續進逼的威脅後,這些演員們也開始轉換了自己的想法,想要好好的幫助這些老實的外星人。當你真的把自己當作是英勇的星際艦隊之後,做出來的也就跟英勇的星際艦隊一樣了。到了後來,外星人知道了他們只是演員,演員們也坦承不諱,但演員跟外星人仍然相互幫助,一起打敗了壞蛋外星人。

有時候人缺的就是相信自己,在不相信的情況下,就會被自己困住。這些演員們原本只是逢場作戲,到了後來,認為自己是可以辦的到的,於是他們就真的辦到了。我的老同學說,我是個自我否定很強的人,是的,的確算是,我的確會懷疑自己有沒有這個能力可以做到。現在也算是慢慢能淡然處之,該做些什麼就去做,該嘗試什麼就去嘗試,這樣才能真正知道能不能做到。

दंगल

在電影台看好幾次了,這次總算是完整看完,很讓人感動的故事。

爸爸過往是個摔角選手,得獎紀錄輝煌,但因為家庭因素,決定放棄摔角事業,回歸家庭。本來想生個兒子來承繼摔角,但往往事與願違,跟太太生了四個女兒。就在心灰意冷的時候,一次女兒的打架事件,讓他發現了兩個女兒吉塔跟巴比塔的天賦,於是跟太太講好,要花一年的時間來訓練看看,如果不行,就放她們回去唸書,不再摔角。吉塔跟巴比塔很不樂意接受這樣的訓練,在學校被同學笑,鄰居也笑他們家怎麼會讓女兒練摔角呢?讓吉塔跟巴比塔轉變念頭的,是一個同學的婚禮,他們的同學也才十幾歲,就被嫁出去了。她哭著跟吉塔跟巴比塔說,「我很羨慕你們,你們的父親選擇了一條可以讓你們未來可以自由選擇的路,像我,就沒得選。」吉塔跟巴比塔這下才明白父親的苦心,於是轉了個念頭,認真接受父親的訓練。

在父親有心栽柳,而柳樹 (吉塔跟巴比塔) 又爭氣的情況下,一邊訓練,一邊以賽代訓,吉塔跟巴比塔漸漸打出了名氣。甚至打進了大學,參加了學校的摔角隊。吉塔上了外地的學校後,迷失了自己的方向,跟父親起了衝突。在參加校際比賽時也因為沒有認真練習而沒拿到好成績。後來,妹妹巴比塔也跟著上了大學,吉塔才因為妹妹巴比塔跟父親和解。爸爸也離開,住到學校附近,就近指導吉塔,吉塔重新找回方向,慢慢也有了好成績。

很快就到了大英帝國運動會,吉塔跟巴比塔也代表國家參加了摔角比賽。巴比塔沒懸念的,拿到冠軍,吉塔則是在四強賽遇到了勁敵,父親預先看過對手比賽影片,指導了吉塔,順利進入決賽。吉塔的教練卻因此眼紅,在決賽當天,找人隔離了吉塔的父親。吉塔陷入苦戰,比賽快結束的時候,吉塔想起了父親的教誨,「爸爸不能時刻都能來就你,你要靠自己。」,並且想出對策,巧妙的誘敵,並使出後背摔,漂亮地拿下分數,取得優勝。

我從電影學到兩件事情,第一件事情,就是你必須要時刻充實自己,讓自己可以站到一個能做出好選擇的位置。也許,隨遇而安是比較輕鬆的選擇,但是在事情來的時候,往往會驚慌,甚至後悔自己之前沒有好好的做好準備。第二件事情就是,無論在什麼緊急的情況,保持冷靜與理智,才是致勝的關鍵所在。

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