跳至主要內容

NMF (HALS) 的實作

· 1 分鐘閱讀
import numpy as np

X = np.array([[1, 1], [2, 1], [3, 1.2], [4, 1], [5, 0.8], [6, 1]])

n_components, n_samples, n_features, = (2,) + X.shape
W = np.random.uniform(size = (n_samples, n_components))
H = np.random.uniform(size = (n_components, n_features))

eps = 1e-4

# NMF
for i in range(100):
# update B
A = X.T.dot(W)
B = W.T.dot(W)
for j in range(n_components):
tmp = H[j, :] + A[:, j] - H.T.dot(B[:, j])
H[j, :] = np.maximum(tmp, eps)

# update A
C = X.dot(H.T)
D = H.dot(H.T)
for j in range(n_components):
tmp = W[:, j] * D[j, j] + C[:, j] - W.dot(D[:, j])
W[:, j] = np.maximum(tmp, eps)
norm = np.linalg.norm(W[:, j])
if norm > 0:
W[:, j] /= norm

print(W)
print(H)
print(W.dot(H))

在 brew 環境下無法安裝 nokogiri 時的解決方法

· 1 分鐘閱讀

發生了以下兩個錯誤:

zlib is missing; necessary for building libxml2
xslt is missing. Please locate mkmf.log to investigate how it is failing.

解決方法

  • 安裝 libxslt 與 libxml2
  • 指定 brew 安裝的 libxml2 路徑
brew install libxslt libxml2
bundle config build.nokogiri --use-system-libraries --with-xml2-include=$(brew --prefix libxml2)/include/libxml2

參考網站

WSL 上的 DNS 配置

· 3 分鐘閱讀

這篇備忘錄記錄了在 WSL(Windows Subsystem for Linux)上配置 DNS 的方法。

資訊

WSL 允許你在 Windows 上運行 Linux 環境,但有時網絡配置(尤其是 DNS)可能會遇到問題。了解如何正確配置 DNS 可以確保你的 WSL 環境能夠正常解析域名。

WSL 中的 DNS 工作原理

默認情況下,WSL 會嘗試從 Windows 主機獲取 DNS 配置。這通常是通過在 WSL 虛擬機中生成 /etc/resolv.conf 文件來實現的。這個文件通常包含一個指向 Windows DNS 服務的 IP 地址,例如 172.X.X.X

常見問題

  • 無法解析域名:這是最常見的問題,表現為無法訪問互聯網或特定服務。
  • DNS 解析速度慢:有時默認配置會導致 DNS 查詢變慢。

解決方法

方法 1:禁用 /etc/resolv.conf 的自動生成 (推薦)

WSL 每次啟動時都會自動重新生成 /etc/resolv.conf。禁用此功能可以讓你手動配置 DNS。

  1. 創建或編輯 wsl.conf 文件

    在 WSL 環境中,創建或編輯 /etc/wsl.conf 文件:

    sudo vim /etc/wsl.conf

    添加以下內容:

    [network]
    generateResolvConf = false

    保存並退出。

  2. 重啟 WSL

    在 PowerShell 或 CMD 中,終止 WSL 以使其應用更改:

    wsl --shutdown

    然後重新啟動你的 WSL 發行版。

  3. 手動編輯 /etc/resolv.conf

    現在,你可以手動編輯 /etc/resolv.conf 並添加你喜歡的 DNS 服務器。例如,使用 Google DNS:

    sudo vim /etc/resolv.conf

    添加以下內容:

    nameserver 8.8.8.8
    nameserver 8.8.4.4

    保存並退出。

    注意

    如果你在 wsl.conf 中設置了 generateResolvConf = false/etc/resolv.conf 將不再被自動覆蓋。

方法 2:在 Windows 中配置 DNS

WSL 從 Windows 繼承 DNS 設置,因此你也可以直接在 Windows 的網絡適配器設置中更改 DNS 服務器。

  1. 打開 網絡和 Internet 設置 -> 更改適配器選項
  2. 右鍵點擊你的網絡連接(例如 Wi-Fi 或乙太網),選擇 屬性
  3. 選擇 Internet 協議版本 4 (TCP/IPv4),然後點擊 屬性
  4. 選擇 使用下列 DNS 服務器地址,然後輸入你偏好的 DNS 服務器,例如 Google DNS (8.8.8.8 和 8.8.4.4)。
  5. 點擊 確定 保存更改。

重啟你的 WSL 發行版,它應該會自動獲取新的 DNS 設置。

方法 3:使用 netsh (Windows 命令)

在某些情況下,你可以使用 netsh 命令來重置或配置 Windows 的 DNS 緩存。

ipconfig /flushdns
netsh interface ip delete dns "乙太網" all
netsh interface ip add dns "乙太網" 8.8.8.8 index=1

將 "乙太網" 替換為你的實際網絡適配器名稱。

測試 DNS 解析

你可以使用 pingdig 命令來測試 DNS 解析是否正常工作:

ping google.com

sudo apt install dnsutils # 如果沒有安裝 dig
dig google.com

總結

通過禁用 /etc/resolv.conf 的自動生成並手動配置,或者直接在 Windows 中更改 DNS 設置,你可以有效地解決 WSL 中的 DNS 問題。選擇適合你的方法,以確保 WSL 環境的網絡連接穩定可靠。

Windows OpenSSH Permission denied 問題

· 1 分鐘閱讀
  • 可以使用密碼登入(雖然設定中已停用)
  • 使用公鑰驗證時發生 Permission denied

連線至 localhost:22 時,出現以下錯誤:

hikari@localhost: Permission denied (publickey,keyboard-interactive).

image

原因

Administrators 群組(即「系統管理員使用者」)預設會從 C:\ProgramData\ssh\administrators_authorized_keys 讀取公鑰進行驗證。

需要將其改為 $env:userprofile\.ssh\authorized_keys

解決方法

以系統管理員權限開啟 C:\ProgramData\ssh\sshd_config,將以下兩行註解掉:

image

- Match Group administrators
- AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
+ #Match Group administrators
+ # AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

儲存後,重新啟動服務。

Restart-Service sshd

Termux 上的 Powerline

· 2 分鐘閱讀

這篇備忘錄記錄了在 Termux 上安裝和配置 Powerline 的方法。

資訊

Powerline 是一個為各種 Shell(如 Bash、Zsh)和編輯器(如 Vim)提供美觀且功能豐富的狀態欄插件。它顯示有用的信息,如當前 Git 分支、Vim 模式、Python 虛擬環境等。

安裝步驟

1. 更新 Termux 套件

在安裝任何新軟體之前,建議先更新 Termux 的套件列表:

pkg update && pkg upgrade

2. 安裝必要的套件

Powerline 需要 Python 環境。此外,為了顯示特殊字元(如箭頭),你需要安裝一個支持 Powerline 字體。

pkg install python python-pip
pkg install git

3. 安裝 Powerline

使用 pip 安裝 Powerline:

pip install --user powerline-status

安裝完成後,Powerline 的可執行文件會位於 ~/.local/bin/

4. 配置 Shell

你需要將 Powerline 添加到你的 Shell 配置中。這裡以 Bash 為例。

編輯 ~/.bashrc 文件:

vim ~/.bashrc

在文件末尾添加以下內容:

# Powerline
export PATH="$PATH:$HOME/.local/bin"
powerline-daemon -q
POWERLINE_BASH_CONTINUATION=1
POWERLINE_BASH_SELECT=1
. ~/.local/lib/python*/site-packages/powerline/bindings/bash/powerline.sh

保存並退出,然後重新載入 ~/.bashrc

source ~/.bashrc

5. 安裝 Powerline 字體

為了讓 Powerline 正確顯示特殊字元,你需要一個 Powerline 字體。在 Termux 中,你可以直接安裝。

pkg install termux-api
termux-setup-storage

然後,你可以下載並安裝一個 Powerline 字體。由於 Termux 的環境限制,直接修改系統字體可能比較麻煩。一種常見的做法是使用支持 Powerline 的終端模擬器(如 Termux 的默認字體通常已支持)。

如果你在其他 Linux 環境下,你可以安裝 fonts-powerline

sudo apt install fonts-powerline

或者手動下載並安裝字體。

6. 配置 Powerline 主題 (可選)

Powerline 允許你自定義狀態欄的外觀。你可以創建自己的配置或修改現有的配置。

通常,配置文件位於 ~/.config/powerline/。你可以複製預設配置進行修改:

mkdir -p ~/.config/powerline
cp -r ~/.local/lib/python*/site-packages/powerline/config_files ~/.config/powerline/

然後編輯 ~/.config/powerline/config.json~/.config/powerline/themes/shell/default.json

總結

通過上述步驟,你可以在 Termux 上成功安裝和配置 Powerline,為你的命令行界面帶來更美觀和信息豐富的狀態欄。這將極大地提升你的終端使用體驗。

Termux 上的 SSH

· 3 分鐘閱讀

這篇備忘錄記錄了在 Termux 上使用 SSH 的方法。

資訊

Termux 是一個 Android 上的終端模擬器和 Linux 環境應用程式,它允許你運行許多 Linux 命令和工具。SSH 是一種安全的網絡協議,用於在不安全的網絡上安全地執行網絡服務。

在 Termux 中,你可以將其作為 SSH 客戶端連接到遠端服務器,也可以將其設置為 SSH 服務器,以便從其他設備連接到你的 Android 設備。

1. 作為 SSH 客戶端

安裝 OpenSSH

Termux 提供了一個 OpenSSH 套件,你可以通過 pkg 命令安裝:

pkg update && pkg upgrade
pkg install openssh

連接到遠端服務器

安裝完成後,你可以使用 ssh 命令連接到遠端服務器:

ssh user@hostname_or_ip

例如:

你也可以使用 SSH 密鑰進行身份驗證,這比密碼更安全。

生成 SSH 密鑰

如果尚未生成,你可以在 Termux 中生成 SSH 密鑰對:

ssh-keygen

按照提示操作,通常可以直接按 Enter 使用默認值。公鑰會保存在 ~/.ssh/id_rsa.pub,私鑰在 ~/.ssh/id_rsa

上傳公鑰到遠端服務器

將你的公鑰複製到遠端服務器的 ~/.ssh/authorized_keys 文件中:

ssh-copy-id user@hostname_or_ip

或者手動複製:

cat ~/.ssh/id_rsa.pub | ssh user@hostname_or_ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

2. 作為 SSH 服務器

啟動 SSH 服務器

Termux 內置了一個 SSH 服務器。默認情況下,它在端口 8022 上運行。 要啟動 SSH 服務器,只需運行 sshd 命令:

sshd
注意

每次 Termux 應用程式關閉或設備重啟後,你都需要重新運行 sshd 命令來啟動 SSH 服務器。

設置 SSH 密碼

如果你想使用密碼連接,你需要為你的 Termux 用戶設置一個密碼:

passwd

輸入並確認你的密碼。

從其他設備連接

現在,你可以從你的電腦或其他設備連接到 Termux SSH 服務器。你需要知道你的 Android 設備在局域網中的 IP 地址。

在你的電腦上:

ssh -p 8022 user@android_device_ip

其中 user 是你的 Termux 用戶名(通常是 u0_aXXX 這樣的字串,但對於 Termux SSH 服務器,你可以直接使用 sshd 運行時的用戶名,通常是 root 或者你當前的 shell 用戶)。

查找 Termux 用戶名

你可以在 Termux 中運行 whoami 命令來查看當前用戶名。 更可靠的方法是,當你啟動 sshd 後,它會使用當前的用戶身份。如果你沒有顯式設置用戶,它可以是 root (如果你以 root 權限運行) 或者默認的 Termux 用戶。

停止 SSH 服務器

要停止 SSH 服務器,你可以找到 sshd 進程並終止它:

pkill sshd

總結

Termux 提供了強大的 SSH 功能,無論是作為客戶端還是服務器,都能極大地增強你的 Android 設備的實用性。這使得在手機上進行開發、遠端管理或其他基於 SSH 的任務變得可能。

在 Windows 上停用 OpenSSH 的密碼驗證

· 1 分鐘閱讀

開啟具有系統管理員權限的終端機

編輯設定檔需要系統管理員權限,請以系統管理員身份開啟終端機。

在終端機圖示上按右鍵,選擇「以系統管理員身份執行」。

image

image

在終端機中開啟設定檔

執行以下命令:

notepad C:\ProgramData\ssh\sshd_config

image

編輯設定檔

- # PasswordAuthentication yes
+ PasswordAuthentication no

image

變更為

image

並儲存變更。

重新啟動 SSH 伺服器

返回終端機,執行以下命令以重新啟動 SSH 伺服器:

Restart-Service sshd

連線測試

測試設定是否已生效。

執行以下命令,若看到以下訊息:

ssh localhost
user@localhost: Permission denied (publickey,keyboaard-interactive).

即表示設定正確。

SSH 隧道

· 3 分鐘閱讀

這篇備忘錄記錄了 SSH 隧道。

什麼是 SSH 隧道?

資訊

SSH 隧道(也稱為 SSH 端口轉發)是一種通過 SSH 連接在客戶端和服務器之間創建加密隧道的方法。它允許你將網絡流量從一個端口轉發到另一個端口,即使這些端口原本無法直接訪問。

SSH 隧道有三種類型:

  1. 本地端口轉發 (Local Port Forwarding):將本地機器的端口轉發到遠端機器的端口。
  2. 遠端端口轉發 (Remote Port Forwarding):將遠端機器的端口轉發到本地機器的端口。
  3. 動態端口轉發 (Dynamic Port Forwarding):創建一個 SOCKS 代理,允許通過 SSH 連接動態轉發多個目的地。

1. 本地端口轉發 (Local Port Forwarding)

用途:訪問防火牆後的遠端服務。

語法:

ssh -L [本地端口]:[目標主機]:[目標端口] [SSH用戶]@[SSH服務器]

範例: 假設你本地機器上的 8080 端口,通過 SSH 服務器(ssh.example.com)將流量轉發到遠端機器(remote.example.com)的 80 端口。

ssh -L 8080:remote.example.com:80 [email protected]

現在,你可以通過訪問本地的 localhost:8080 來訪問 remote.example.com 上的網頁服務。

2. 遠端端口轉發 (Remote Port Forwarding)

用途:讓遠端機器訪問本地機器上的服務。

語法:

ssh -R [遠端端口]:[目標主機]:[目標端口] [SSH用戶]@[SSH服務器]

範例: 假設你希望遠端 SSH 服務器上的用戶可以通過 localhost:9000 訪問你本地機器上的 3000 端口(例如一個 Web 應用)。

ssh -R 9000:localhost:3000 [email protected]

現在,連接到 ssh.example.com 的用戶可以通過訪問 localhost:9000 來訪問你的本地服務。

3. 動態端口轉發 (Dynamic Port Forwarding)

用途:創建一個 SOCKS 代理,用於繞過防火牆或匿名上網。

語法:

ssh -D [本地端口] [SSH用戶]@[SSH服務器]

範例: 在本地機器上創建一個 SOCKS 代理,監聽 8181 端口。

ssh -D 8181 [email protected]

然後,你需要將你的瀏覽器或其他應用程式配置為使用 localhost:8181 作為 SOCKS 代理。所有通過這個代理的流量都將通過 ssh.example.com 加密隧道轉發。

保持隧道開啟

如果你希望 SSH 隧道在後台保持運行,可以使用 -N(不執行遠端命令)和 -f(在後台運行)選項:

ssh -fN -L 8080:remote.example.com:80 [email protected]

總結

SSH 隧道是一個非常強大且靈活的工具,它提供了安全地訪問網絡服務、繞過網絡限制以及增強隱私保護的方法。了解並熟練使用不同類型的端口轉發,可以大大提高你的網絡操作效率和安全性。

如何安裝 Powerline

· 1 分鐘閱讀

安裝 Go

安裝 Go 以便安裝 powerline-go。

brew install go

安裝 Powerline-go

go get -u github.com/justjanne/powerline-go

設定

Bashrc

用 Vim 或 nano 開啟 ~/.bashrc,並加入以下內容。

GOPATH=$HOME/go
function _update_ps1() {
PS1="$( $GOPATH/bin/powerline-go -newline -error $? )"
}
if [ "$TERM" != "linux" ] && [ -f "$GOPATH/bin/powerline-go" ]; then
PROMPT_COMMAND="_update_ps1; $PROMPT_COMMAND"
fi

執行 source ~/.bashrc 套用變更。

字型

到這裡應該就完成了,但可能會有字元編碼問題。 您需要設定對應 Powerline 的字型。 在 Windows 上,可以使用 Cascadia Code PL 或 Cascadia Mono PL。

推薦使用 https://github.com/yuru7/PlemolJP/ 的 PlemolJP。 從 https://github.com/yuru7/PlemolJP/releases 下載,點擊 PlemolJP_NF_vX.X.X.zip,下載後解壓縮並安裝字型。 將字型設定為 PlemolJP35 Console NF。

避免在 Arduino 中使用 delay()

· 1 分鐘閱讀

在 Arduino 中使用 delay() 會導致等待期間無法執行任何其他動作。 這裡使用 millis() 建立了一個以 1 秒週期閃爍 LED 的程式。

  1. 使用 millis() 取得時間,除以間隔後將結果指派給 t
  2. 比較前一個 t 與新的 t,若不同則執行函式。

範例

unsigned long t = 0, ot;

void sетуp(){
pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
ot = t;
t = millis() / 500;
if(ot != t){
if(t % 2){
digitalWrite(LED_BUILTIN, LOW);
}else{
digitalWrite(LED_BUILTIN, HIGH);
}
}
}