# LINE BOT課程常見問題
# 最難調試排行榜
## <a href="#Verify後-404-NOT-FOUND" style="color: black; text-decoration: underline">No.1 Verify後 `404 NOT FOUND`</a>
#### 請把 `@app.route("/callback", methods=['POST'])` 改成 `@app.route("/", methods=['POST'])`
#### 或將Webhook URL後`/`變成`/callback`
## <a href="#PY程式或gunicorn運行時失敗" style="color: black; text-decoration: underline">No.2 沒關翻譯器就複製 ACCESS TOKEN</a>
## <small>No.3 (從缺)</small>
# 速覽
[TOC]
# 本筆記的約定
## 我們將使用`<>`表示需要替換的地方
## 部分問題含有內文可以深入認識
# 大部分的資料來源
#### `<命令> --help`
#### `help <命令>`
#### `man <命令>`
#### `info <命令>`
# WSL相關
## adduser: Please enter a username matching the regular expression configured
#### WSL使用者名稱只允許\[小寫英文字母\]、\[0~9\]、\[_\]、\[-\],且不超過32個字元
## \<username\> is not in the sudoers file.
#### 在cmd或powershell輸入 `wsl -u root` 並輸入 `usermod -aG sudo <username>`,並關閉所有wsl,等待8秒後(自動關機wsl)重啟wsl,你也可以在cmd或powershell執行`wsl --shutdown`來手動關機
# Linux 內建命令
## rm: cannot remove '資料夾': Is a directory
#### 當你嘗試刪除一個包含內容的資料夾時,就會報錯,運行 rm -rf <資料夾路徑>
`-r`,`-R`,`--recursive` 表示「遞迴」刪除資料夾內資料夾與檔案
`-f`,`--force` 為強制
有些需要強制刪除者可使用`-rf`跳過
## 別把`cat`和`ls`、`cd`用錯對象
#### `cat`負責輸出檔案內容,`ls`負責輸出資料夾內部,`cd`負責進入資料夾
# 應用相關
## 我打開了個未知的文檔查看器,我該如何退出
#### 這通常是vi/vim系列,`:q`即可
## 如何儲存與退出nano
#### 儲存: Ctrl+O / 退出: Ctrl+X
# 伺服器相關
## 如何查看已使用空間
#### quota -s 或 du -hs ~
`quota`意指"扣打",也就是配額
`-s`或`--human-readable[=units]` 會使用如K,M,G等單位顯示
此指令會有如下輸出
```
Filesystem space quota limit grace files quota limit grace
/dev/sda1 59188K 100M 100M 4279 0 0
```
space是當前使用量,quota和limit為最大限制,歡迎在留言區補充這兩個的差別
`du [FILE]...` 會輸出檔案或遞迴計算資料夾的使用空間
`-h`或`--human-readable[=units]` 會使用如K,M,G等單位顯示
`-s, --summarize` 不會一一列出資料夾中各檔案、資料夾與自身的空間,而只有自身的空間
## 設定權限
#### chmod <擁有者權限(0-7)><群組權限(0-7)><訪客權限(0-7)> <檔案>
#### 網站權限設置:chmod 755 ~/www/
## 如何在無法sudo下安裝套件
#### https://askubuntu.com/a/350
舉個例子,倘若我們想要安裝`tree`
```bash
apt download tree
dpkg-deb -x tree*.deb tree_deb
```
以下是`tree_2.0.2-1_amd64.deb`的結構
```
tree_deb
└── usr
├── bin
│ └── tree
└── share
├── doc
│ └── tree
│ ├── README.gz
│ ├── TODO
│ ├── changelog.Debian.gz
│ └── copyright
└── man
├── fr
│ └── man1
│ └── tree.1.gz
└── man1
└── tree.1.gz
```
其中`tree_deb/usr/bin/tree`就是我們想要的可執行檔,而且幸運的是,tree的依賴項`libc6`已經安裝且此程式很簡單,直接運行:
```bash
mv tree_deb/usr/bin/tree ~/.local/bin/
```
- 移動到此目錄的原因是`PATH`這個系統尋找執行檔的環境變量包含此路徑
- 你可以透過`echo $PATH`得知PATH包含的
- `apt-cache depends <package>`可查看依賴項
- `apt show <package>`可查看包詳情
- `apt search <keyword>`可查詢包
- `dpkg -l [<pattern>...]`可確認是否已安裝某包
- `dpkg-deb -x <deb> <dir>`可將一個deb包提取到dir資料夾中
# Python相關
## Command 'python' not found
#### 請改為`python3`或運行`sudo rm /usr/bin/python && ln -s /usr/bin/python3 /usr/bin/python`
## .PY程式或gunicorn運行時失敗
#### 確定程式複製完整
#### 括號、引號不要漏、都必須成雙成對
#### TOKEN、SECRET確定和LINE開發者網頁顯示一致
#### gunicorn和ngrok的port必須一致
#### <div style="background-color: black; color: red"><b>\>注意事項\< </b><br></b><div>關掉翻譯器再複製ACCESS TOKEN、SECRET
## 為甚麼我不能用`venv`、`act`、`deact`
#### 要在~/.bashrc 加入alias指令
```bash
alias venv='python -m venv'
alias act='source .venv/bin/activate || source bin/activate
alias deact='deactivate'
```
`alias: alias [-p] [name[=value] ... ]`
本指令可用於縮減指令,本質上是一個變數調用
#### <div style="background-color: black; color: red"><b>>注意事項<</b><br>bash中,是不允許`=`兩邊加空格的,程式一般以空格區隔引數</div>
## 開啟activate時報錯
#### 請改用`source <path>/bin/activate`開啟
# AI 相關
## Verify後 `404 NOT FOUND`
#### 請把 `@app.route("/callback", methods=['POST'])` 改成 `@app.route("/", methods=['POST'])`
#### 或將Webhook URL後`/`變成`/callback`
ChatGPT: https://chat.openai.com/share/baccb0db-b0c0-4736-8d7f-33af48bf559c
Bard: https://g.co/bard/share/915f362d0674
Claude: (代碼和邏輯與ChatGPT相差不遠)
關於這件事來自ChatGPT和Claude,Bard不知道在幹嘛
由於[Github的v2示例](https://github.com/line/line-bot-sdk-python/blob/3e5d4b6de67875ad40453b6b62d13d29d4baf2a1/examples/flask-echo/app.py)使用`callback`為Flask路徑,而不是我們給的示例`/`,所以callback的地方不同,就會報Error 404,gunicorn也接收不到,這就是我將它放在第一名的原因。
# gunicorn/ngrok相關
## 如何殺掉gunicorn
#### killall -u $(whoami) gunicorn
`-u USER` 代表尋找由`USER`運行的進程
`whoami` 會輸出使用者名字
`"$(command)"`會運行command並將回傳的值取代掉這一串指令
## 如何查看gunicorn是否運行
#### `pgrep -a gunicorn`
`pgrep <pattern>`是一個用來查找process的指令,`grep`從`ed`的同效輸出`g/re/p`來命名的<sup><a href="https://w.wiki/87oQ">[1]</a></sup>
預設會印出PID<small>(<b>P</b>rocess <b>Id</b>entifier)</small>
`-a`或`--list-full` 會輸出process的完整指令
`-u <ID,...>`或`--euid <ID,...>`可以匹配用戶,可搭配`id -u`匹配自己
## 如何調試gunicorn
#### `killall -u $(whoami) gunicorn`,並在運行gunicorn時去掉` --daemon`
## gunicorn運行時ModuleNotFoundError
#### 確保已經進入虛擬環境(venv),並已安裝插件
虛擬環境啟動命令
```
source <venv_path>/bin/activate
```
Module安裝命令
```
pip install Flask line-bot-sdk gunicorn
```
## ngrok 502 error
#### GUNICORN和NGROK的PORT設定不一致
#### 沒有驗證NGROK([官網](https://ngrok.com/))
## [ERROR] Can't connect to ('127.0.0.1', 8000)
#### 表示啟用了多個gunicorn並引起port衝突
# 考試相關
#### 本機要運行gunicorn和ngrok,Line Webhook URL填ngrok給的網址;伺服器端只要跑gunicorn,Line Webhook URL打`https://app1.********/531xx/`