跳至主要內容

標籤「Linux」的 19 篇文章

查看所有標籤

Makefile 的推薦

背景與問題意識​

在日常工作中,使用 Python 腳本進行資料轉換自動化時,常常會遇到以下問題:

  • 明明只更新了原始資料的一部分,卻得整體重新執行,白白浪費時間。
  • 哪個步驟依賴哪個檔案不夠清楚,難以管理執行順序與遺漏情況。
  • 不容易掌握腳本修改會影響哪些產出物。

Makefile 具備「相依關係」與「只重跑差異部分(增量建置)」這些標準功能,能用很少的描述解決上述問題。

Make 的基本概念​

  • 目標(target):產出物(例:output/report.csv)
  • 相依關係(dependency):產出所需的檔案(例:data/clean/*.csv 或腳本)
  • 配方(recipe):用來產出的指令(例:python scripts/aggregate.py ...)

Make 會在「相依關係比目標更新」時才執行配方。如此一來,當原始資料或 Python 腳本更新時,只會自動重跑必要的部分。

最小構成的 Makefile 範例​

以下是一個將 raw 資料清理後,再產生彙總報表的差異執行範例。

# Makefile
SHELL := bash
.SHELLFLAGS := -eu -o pipefail -c
.DELETE_ON_ERROR:
.ONESHELL:
.DEFAULT_GOAL := all

RAW_DIR := data/raw
CLEAN_DIR := data/clean
OUT_DIR := output

RAW := $(wildcard $(RAW_DIR)/*.csv)
CLEAN := $(patsubst $(RAW_DIR)/%.csv,$(CLEAN_DIR)/%.csv,$(RAW))
REPORT := $(OUT_DIR)/report.csv

# 目錄為順序相依(不存在時建立,但不作為更新判定依據)
$(CLEAN_DIR) $(OUT_DIR):
mkdir -p $@

# 彙總報表依賴已清理的 CSV 與彙總腳本
$(REPORT): $(CLEAN) scripts/aggregate.py | $(OUT_DIR)
python scripts/aggregate.py -i $(CLEAN_DIR) -o $@

# 由各 raw CSV 產生對應的 clean CSV
$(CLEAN_DIR)/%.csv: $(RAW_DIR)/%.csv scripts/clean.py | $(CLEAN_DIR)
python scripts/clean.py -i $< -o $@

.PHONY: all clean status

all: $(REPORT)

clean:
rm -rf $(CLEAN_DIR) $(OUT_DIR)

# 確認哪些項目會被重建的輔助指令
status:
@echo "RAW : $(RAW)"
@echo "CLEAN : $(CLEAN)"
@echo "REPORT: $(REPORT)"
@echo
@echo "Dry-run (what would run):"
@$(MAKE) -n all

透過這個架構,可以達成以下效果:

  • 更新原始資料 data/raw/foo.csv 時,只會重新產生對應的 data/clean/foo.csv。
  • 更新 scripts/clean.py 時,只會在必要範圍內重新執行清理流程。
  • 更新 scripts/aggregate.py 時,只會重新執行彙總報表。

動作示意​

# 第一次執行(全部產生)
make -j

# 部分 raw 更新(只重新執行該檔案的清理與報表)
touch data/raw/a.csv
make -j

# 清理腳本更新(重新執行所有清理與報表)
touch scripts/clean.py
make -j

# 彙總腳本更新(只重新執行報表)
touch scripts/aggregate.py
make

想事先確認「會執行什麼」時,make -n 很有用。

腳本相依性的設計指引​

  • 每個規則都應明確將其直接呼叫的 Python 腳本列為相依關係,這很重要。
  • 若拆分成多個模組,應將目標規則所 import 的模組也納入相依關係,才能正確傳遞變更。簡便作法是把目標目錄下所有 Python 檔案變成變數,再加進相依關係中。

例(簡便作法):

PY_SRCS := $(wildcard scripts/**/*.py) $(wildcard scripts/*.py)

$(CLEAN_DIR)/%.csv: $(RAW_DIR)/%.csv $(PY_SRCS) | $(CLEAN_DIR)
python scripts/clean.py -i $< -o $@

平行執行與加速​

  • 透過 make -j 可以將彼此獨立的檔案轉換平行化。資料點越多,效果越明顯。
  • 中間產物切得越細,增量執行越有效,也越能避免整體重算。
  • 若 I/O 是瓶頸,可搭配壓縮格式、檔案分割、或本機 SSD 使用。

實務上的訣竅​

  • 目錄建立使用順序相依(| dir)處理,可避免不必要的重建。
  • 為了在失敗時不留下不完整產物,建議啟用 .DELETE_ON_ERROR。
  • 常用入口可用 .DEFAULT_GOAL := all 標準化,讓 make 一次就能執行。
  • 除錯時可使用 make -n(只顯示不執行)、make --trace(顯示為何會執行)、make -d(詳細日誌)。
  • 清理請使用 .PHONY: clean,並注意只刪除生成物。

虛擬環境與依賴套件(選用)​

Python 執行環境也可以交由 Make 管理。

VENV := .venv
PY := $(VENV)/bin/python

$(VENV)/bin/python: requirements.txt
python3 -m venv $(VENV)
$(VENV)/bin/pip install -r requirements.txt
touch $@

# 後續配方中使用 $(PY)
$(CLEAN_DIR)/%.csv: $(RAW_DIR)/%.csv scripts/clean.py | $(CLEAN_DIR) $(VENV)/bin/python
$(PY) scripts/clean.py -i $< -o $@

$(REPORT): $(CLEAN) scripts/aggregate.py | $(OUT_DIR) $(VENV)/bin/python
$(PY) scripts/aggregate.py -i $(CLEAN_DIR) -o $@

更新 requirements.txt 時,只會在必要範圍內重新完成設定。

總結​

  • Makefile 是一種能自動化「明確相依關係」與「只重跑差異部分」的工具,能大幅提升資料轉換流程的可靠性與開發速度。
  • 正確連結原始資料、腳本與產出物,並將處理細化後,更新影響的範圍就能被快速重新計算。
  • 以最少的描述即可獲得可重現性、平行化與可觀測性,讓日常自動化工作變得更加順手。

新功能 Amazon S3 Files 讓 S3 桶可以掛載到 EC2

Amazon S3 Files 是一項可以將 S3 桶直接掛載到 EC2 等計算資源的服務,並且以 NFS 檔案系統的形式運行。資料保持在 S3 中,可以使用一般的檔案操作(ls、cp、cat 等)進行讀寫。

S3 Files 是什麼​

S3 Files 是基於 Amazon EFS 建立的共享檔案系統,讓使用者能以檔案系統的形式存取 S3 桶中的數據。

主要特點如下:

項目內容
協定NFS 4.1 / 4.2
支援的計算資源EC2、Lambda、ECS、EKS
同時連接數量最多 25,000 個計算資源
讀取吞吐量最大 TB/秒
IOPS超過 1,000 萬/桶
加密TLS(傳輸中)+ AWS KMS(儲存時)
檔案系統功能POSIX 權限、檔案鎖定、讀取後寫入一致性

運作原理​

S3 Files 將被訪問的資料自動載入高效能儲存系統,並以低延遲的方式提供服務。

  • 小檔案(預設小於 128 KB):直接從高效能儲存中讀取
  • 大檔案(1 MB 以上):直接從 S3 流式傳輸
  • 寫入:在高效能儲存中寫入後,自動同步到 S3

高效能儲存中的資料,如果在一定時間內(預設 30 天,可設置為 1 - 365 天)未被訪問,將自動刪除。

前提條件​

  • AWS 帳戶
  • EC2 實例(Linux)
  • S3 桶(與 EC2 相同區域)
  • 兩個 IAM 角色
    • 建立檔案系統用:對 S3 桶的讀寫權限
    • EC2 實例用:附加 AmazonS3FilesClientFullAccess 管理策略
  • 安全群組:允許 NFS 的 2049 端口通訊

IAM 角色的建立​

S3 Files 需要兩個 IAM 角色。

1. 用於建立檔案系統的角色​

使用管理控制台時會自動創建,因此不需要手動創建

此角色用於讓 S3 Files 存取桶。

# 創建角色
aws iam create-role \
--role-name S3Files-FileSystem-Role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "s3files.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}'

# 附加 S3 Files 客戶端策略
aws iam attach-role-policy \
--role-name S3Files-FileSystem-Role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FilesClientFullAccess

在創建檔案系統時用 --role-arn 指定此角色。

2. 用於 EC2 實例的角色​

未附加 IAM 角色會導致掛載失敗

在 CloudShell 中創建以下角色。

# 創建角色
aws iam create-role \
--role-name EC2-S3Files-Role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}'

# 附加 S3 Files 客戶端策略
aws iam attach-role-policy \
--role-name EC2-S3Files-Role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FilesClientFullAccess

# 創建並附加實例檔案配置
aws iam create-instance-profile \
--instance-profile-name EC2-S3Files-Profile

aws iam add-role-to-instance-profile \
--instance-profile-name EC2-S3Files-Profile \
--role-name EC2-S3Files-Role

將此角色附加到實例上。

設定步驟​

1. 準備 S3 桶​

在 S3 控制台中創建通用桶,也可以使用現有的桶。

需要特別注意的是,必須啟用桶的版本控制設定

2. 創建檔案系統​

從控制台創建​

alt text

  1. 在 S3 控制台中選擇桶
  2. 點擊「檔案系統」標籤 → 「創建檔案系統」

從控制台創建後,所有可用區會自動創建掛載目標和存取點。

alt text

  1. 指定前綴和 VPC,然後點擊「創建檔案系統」。

記錄下輸出的檔案系統 ID(例如:fs-0123456789abcdef0)。

3. 在實例中掛載​

在終端中執行以下命令。

# 創建掛載點
sudo mkdir /mnt/s3files

# 挂載
sudo mount -t s3files fs-0123456789abcdef0:/ /mnt/s3files
備註

如果無法掛載,請執行以下命令再試一次:

sudo dnf install -y amazon-efs-utils # Amazon Linux, RHEL
# sudo apt install -y amazon-efs-utils (Ubuntu, Debian)
備註

如果在執行 dnf 命令時通訊出現問題,請設置 S3 端點(網關),並指定與實例相同的可用區。

但要注意,S3 端點的路由表應與實例所在的子網相同。

確認掛載情況:

df -h /mnt/s3files

應顯示類似以下內容:

Filesystem Size Used Avail Use% Mounted on
<s3files-dns> 8.0E 129M 8.0E 1% /mnt/s3files

4. 確認運行​

cd /mnt/s3files

# 創建檔案
sudo sh -c 'echo "Hello, s3 Files!" > test.txt'

# 讀取檔案
cat test.txt

# 創建目錄
sudo mkdir test-directory

ls -la

# 複製檔案
sudo cp test.txt test-directory/

cd test-directory/

# 確認檔案列表
ls -la

寫入的檔案會在約 1 分鐘內與 S3 桶同步。可以在 S3 控制台確認對象已創建。

aws s3 ls s3://<bucket-name>/

自動掛載設定​

為了在重啟後保持掛載,需要將以下內容添加到 /etc/fstab。

# 添加到 /etc/fstab
fs-0123456789abcdef0:/ /mnt/s3files s3files _netdev,nofail 0 0

_netdev 是一個選項,確保在網路連接後再進行掛載,這是必需的。加入 nofail 可以防止掛載失敗時導致實例無法啟動。

收費​

S3 Files 的收費如下:

  • 高效能儲存使用量:檔案系統中數據的儲存費用
  • 檔案系統存取費用:對高效能儲存進行讀寫操作的費用
  • S3 請求費用:對於直接從 S3 讀取大於 1 MB 的檔案,僅收取 S3 GET 費用

為按量計費的無需配置模式,根據 AWS 的說法,與傳統 S3 和檔案系統間數據複製相比可減少最多 90% 的成本。

總結​

  • 使用 S3 Files 可以將 S3 桶掛載為 NFS 檔案系統在 EC2 上
  • 數據保留在 S3 中,可以使用 ls、cat、cp 等正常的檔案操作
  • 透過高效能儲存提供低延遲,未被訪問的數據會自動退避
  • 通過 /etc/fstab 設定自動掛載,即使重啟後也能維持

參考​

使用 pLaTeX 製作日文 PDF 的方法

整理了使用 pLaTeX 製作日文 PDF 文件的步驟。從範本的構成到編譯,以及常見錯誤的處理都會說明。

pLaTeX 是什麼​

pLaTeX 是支援日文組版的 LaTeX 實作。使用 platex 指令編譯 .tex 檔,然後用 dvipdfmx 轉成 PDF。

因為包含在 TeX Live 中,如果已安裝 TeX Live 就可以立即使用。TeX Live 的安裝步驟請參考「在 Linux 上安裝 TeX Live 2026」。

選擇文件類別​

在日文文件中可使用以下類別。

類別用途
jarticle論文、報告等短篇文件
jbook書籍、有章節的長篇文件
jreport技術報告(含 abstract + chapter 結構)
beamer投影片(簡報)

範本(jarticle)​

使用 jarticle 的基本範例如下。

顯示範例程式碼
% pLaTeX 範例文件 — 主要功能概覽
\documentclass[a4paper,12pt]{jarticle}

%% ========== 套件 ==========
\usepackage{amsmath, amssymb} % 數學式強化
\usepackage{graphicx} % 插入圖像
\usepackage{color} % 顏色設定
\usepackage{fancyhdr} % 頁首/頁尾
\usepackage{geometry} % 頁面版面
\usepackage{enumerate} % 列舉自訂
\usepackage{url} % URL 顯示
\usepackage{multicol} % 分欄
\usepackage{booktabs} % 高品質表格線
\usepackage{array} % 表格欄格式擴充
\usepackage{verbatim} % verbatim 環境
\usepackage{ascmac} % 框線環境(screen, itembox 等)
\usepackage{okumacro} % Ruby・圓點等(pLaTeX 常用)
\usepackage{setspace} % 行距調整
\usepackage{listings} % 原始碼清單
\usepackage{xcolor} % 顏色(listings 用)
\usepackage{caption} % 標題樣式

%% ========== 頁面版面 ==========
\geometry{top=25mm, bottom=25mm, left=25mm, right=25mm}
\setlength{\headheight}{17pt}
\addtolength{\topmargin}{-5pt}

%% ========== 頁首/頁尾 ==========
\pagestyle{fancy}
\fancyhf{}
\lhead{pLaTeX 範例文件}
\rhead{\today}
\cfoot{\thepage}
\renewcommand{\headrulewidth}{0.4pt}

%% ========== listings 設定 ==========
\lstset{
basicstyle=\ttfamily\small,
keywordstyle=\color{blue}\bfseries,
commentstyle=\color{green!50!black},
stringstyle=\color{red!70!black},
numbers=left,
numberstyle=\tiny\color{gray},
frame=single,
breaklines=true,
tabsize=4,
}

%% ========== 標題資訊 ==========
\title{\textbf{pLaTeX 主要功能範例}\\[5pt]
\large --- 日文 \LaTeX 的典型用法 ---}
\author{範例太郎\thanks{範例大學 資訊工程系}
\and 範例花子}
\date{\today}

%% ================================================================
\begin{document}
%% ================================================================

\maketitle
\thispagestyle{fancy}

\begin{abstract}
本文檔是示範 pLaTeX 主要功能的範例。
依序說明文件類別與套件的讀入、日文組版特有的功能、
數學式、表格、圖形、交叉參照、腳註、Ruby、圓點、
原始碼清單、分欄、自訂指令等內容。
\end{abstract}

\tableofcontents
\newpage

%% ================================================================
\section{日文組版的基本}
%% ================================================================

\subsection{和文・歐文的混合}

pLaTeX 可以自然地混合日文與歐文。
例如「Hello, World!」或 \texttt{LaTeX2e} 類的
ASCII 文字會自動插入適當的空白。

全形字與半形字之間的間距調整由 pLaTeX 自動處理:
日本語English日本語、數字123日本語、記號\%日本語。

\subsection{Ruby(振假名)}

使用 \texttt{okumacro} 套件的 \verb|\ruby| 指令可以加上 Ruby(振假名)。

\begin{center}
\ruby{漢字}{かんじ}、\ruby{情報処理}{じょうほうしょり}、
\ruby{自然言語}{しぜんげんご}\ruby{処理}{しょり}
\end{center}

\subsection{圓點(傍點)}

使用 \texttt{okumacro} 的 \verb|\kenten| 可以加上圓點(傍點)。

\begin{center}
\kenten{重要な箇所}には圏点を打つことができる。
\end{center}

\subsection{字體大小}

{\tiny 極小} {\scriptsize 腳註} {\footnotesize 小} {\small 稍小}
{\normalsize 標準} {\large 稍大} {\Large 大} {\LARGE 很大}
{\huge 超大} {\Huge 最大}

\subsection{文字裝飾}

\begin{itemize}
\item \textbf{粗體(Bold)}
\item \textit{斜體(英文字)}
\item \textsl{斜向}
\item \textsc{Small Caps}
\item \texttt{等寬字體(Typewriter)}
\item \underline{底線文字}
\item \textcolor{red}{紅色文字}
\item \textcolor{blue!70!black}{藍色文字}
\item \colorbox{yellow}{標示底色}
\end{itemize}

%% ================================================================
\section{文件結構}
%% ================================================================

\subsection{標題層級}

在 pLaTeX(\texttt{jarticle})中可以使用以下標題層級:
\verb|\section|、\verb|\subsection|、\verb|\subsubsection|、
\verb|\paragraph|、\verb|\subparagraph|。

\subsubsection{子子節範例}
這是子子節的範例。

\paragraph{段落標題}
這是段落標題的範例。接續的內文沒有縮排。

\subsection{腳註}

可以在內文中加入腳註\footnote{這是腳註的文字。會自動配置在頁底。}。
也可以使用多個腳註\footnote{第二個腳註。編號會自動遞增。}。

\subsection{交叉參照}

加上 \verb|\label| 之後,
可以用 \verb|\ref| 或 \verb|\pageref| 來參照。
例:下一節是第~\ref{sec:math}~節(第~\pageref{sec:math}~頁)。

%% ================================================================
\section{數學式環境}
\label{sec:math}
%% ================================================================

\subsection{行內數學式與顯示數學式}

行內數學式:$E = mc^2$、$\alpha + \beta = \gamma$、
$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$。

顯示數學式:
\[
\int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}
\]

\subsection{equation・align 環境}

帶編號的數學式(\texttt{equation}):
\begin{equation}
\label{eq:euler}
e^{i\pi} + 1 = 0
\end{equation}
式~\eqref{eq:euler} 為歐拉恆等式。

多行對齊(\texttt{align}):
\begin{align}
(a+b)^2 &= a^2 + 2ab + b^2 \\
(a-b)^2 &= a^2 - 2ab + b^2 \\
(a+b)(a-b) &= a^2 - b^2
\end{align}

\subsection{矩陣・向量}

\begin{equation}
A = \begin{pmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{pmatrix},\quad
\det(A) = a_{11}a_{22} - a_{12}a_{21}
\end{equation}

\subsection{分段、分數、極限}

\begin{equation}
f(x) = \begin{cases}
x^2 & (x \geq 0) \\
-x^2 & (x < 0)
\end{cases}, \qquad
\lim_{n\to\infty} \left(1 + \frac{1}{n}\right)^n = e
\end{equation}

%% ================================================================
\section{表格(tabular 環境)}
%% ================================================================

\subsection{基本表格}

\begin{table}[h]
\centering
\caption{各城市氣溫資料(示意)}
\label{tab:temp}
\begin{tabular}{lrrr}
\toprule
城市 & 最高氣溫 (°C) & 最低氣溫 (°C) & 平均氣溫 (°C) \\
\midrule
東京 & 35.2 & 25.1 & 29.8 \\
大阪 & 36.4 & 26.3 & 31.0 \\
札幌 & 28.7 & 19.5 & 23.9 \\
那覇 & 32.1 & 27.4 & 29.8 \\
\bottomrule
\end{tabular}
\end{table}

\subsection{複雜表格(\texttt{array} 擴充・儲存格合併)}

\begin{table}[h]
\centering
\caption{程式語言比較}
\label{tab:lang}
\begin{tabular}{|l|c|c|c|}
\hline
語言 & 型別 & 範式 & 主要用途 \\
\hline\hline
Python & 動態 & 多範式 & AI/資料分析 \\
Rust & 靜態 & 系統程式 & 系統開發 \\
Haskell & 靜態 & 函數式 & 研究/金融 \\
JavaScript & 動態 & 多範式 & Web 前端 \\
\hline
\end{tabular}
\end{table}

像表~\ref{tab:temp} 與表~\ref{tab:lang} 可以透過 \verb|\label/\ref| 進行參照。

%% ================================================================
\section{列表環境}
%% ================================================================

\subsection{項目符號列表(itemize)}

\begin{itemize}
\item 第一個項目
\item 第二個項目
\begin{itemize}
\item 嵌套項目 A
\item 嵌套項目 B
\end{itemize}
\item 第三個項目
\end{itemize}

\subsection{編號列表(enumerate)}

\begin{enumerate}[(1)] % enumerate 套件指定格式
\item 最初的步驟
\item 下一個步驟
\item 最後的步驟
\end{enumerate}

\subsection{說明列表(description)}

\begin{description}
\item[pLaTeX] 支援日文的 \LaTeX 系統
\item[upLaTeX] 支援 Unicode 的 pLaTeX 後繼版
\item[LuaLaTeX] 可使用 Lua 腳本的 \LaTeX 系統
\end{description}

%% ================================================================
\section{verbatim・原始碼}
%% ================================================================

\subsection{verbatim 環境}

\begin{verbatim}
#include <stdio.h>
int main(void) {
printf("Hello, pLaTeX!\n");
return 0;
}
\end{verbatim}

\subsection{用 listings 做語法高亮}

\begin{lstlisting}[language=Python, caption={費波那契數列(Python)}]
def fibonacci(n: int) -> int:
"""使用遞迴計算費波那契數列"""
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)

# 輸出前 10 項
for i in range(10):
print(f"F({i}) = {fibonacci(i)}")
\end{lstlisting}

%% ================================================================
\section{框線・強調框}
%% ================================================================

可以使用 \texttt{ascmac} 套件的 \texttt{itembox}、\texttt{screen} 等。

\begin{itembox}[l]{重要要點}
\begin{itemize}
\item pLaTeX 使用 \texttt{jarticle} / \texttt{jbook} 文件類別
\item 使用 \texttt{okumacro} 可以用 Ruby 與圓點
\item 以 \texttt{platex + dvipdfmx} 產生 PDF
\end{itemize}
\end{itembox}

\vspace{5pt}

\begin{screen}
\texttt{screen} 環境:終端機風格的框線。用來顯示原始碼範例或輸出範例。
\end{screen}

%% ================================================================
\section{分欄}
%% ================================================================

可用 \texttt{multicol} 套件從某處開始切成兩欄。

\begin{multicols}{2}
\noindent
這是兩欄版面的左欄。
pLaTeX 也能自然處理日文的分欄。
即使是長文也會自動均分,
適合做報章雜誌風格的排版。

\columnbreak

\noindent
這是右欄。
可以用 \verb|\columnbreak| 強制換欄。
數學式 $x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$
也可以行內使用。
\end{multicols}

%% ================================================================
\section{行距・間距調整}
%% ================================================================

\subsection{水平間距}

字與字之間的空格:a\,b(\verb|\,| 細空白)、
a\enspace b(\verb|\enspace|)、
a\quad b(\verb|\quad|)、
a\qquad b(\verb|\qquad|)。

\subsection{垂直間距}

可以用 \verb|\vspace| 新增垂直間距。

\vspace{5mm}
在此插入自上方 5mm 的垂直間距後的文字。
\vspace{5mm}

\subsection{行距}

{\setstretch{1.8}
此段落用 \texttt{setspace} 套件的
\texttt{setstretch} 將行距設為 1.8 倍。
在日文文件中,行距約 1.5〜2.0 較為易讀。
}

%% ================================================================
\section{自訂指令與環境}
%% ================================================================

\subsection{自訂指令定義}

\newcommand{\R}{\mathbb{R}}
\newcommand{\N}{\mathbb{N}}
\newcommand{\highlight}[1]{\colorbox{yellow!60}{#1}}
\newcommand{\term}[1]{\textbf{\textit{#1}}} % 用語強調

範例:$\R$(實數集)、$\N$(自然數)。
\highlight{被標示的文字}。
\term{機器學習}(Machine Learning)是人工智慧的一個領域。

\subsection{自訂環境定義}

\newenvironment{mybox}[1]{%
\begin{center}\begin{tabular}{|p{0.85\linewidth}|}
\hline\vspace{1pt}
\textbf{#1}\\[2pt]
}{%
\\\hline\end{tabular}\end{center}
}

\begin{mybox}{自製的框線}
使用 \verb|\newenvironment| 可以定義自訂環境。
可以接受參數以利彈性重複使用。
\end{mybox}

%% ================================================================
\section{參考文獻}
%% ================================================================

文獻引用可用 \verb|\cite| 指令進行~\cite{knuth1984,lamport1994,okumura2020}。
文件末會輸出參考文獻清單。

%% ================================================================
%% 參考文獻清單(thebibliography 環境)
%% ================================================================
\begin{thebibliography}{99}

\bibitem{knuth1984}
D.~E. Knuth,
\textit{The \TeX book},
Addison-Wesley, 1984.

\bibitem{lamport1994}
L.~Lamport,
\textit{\LaTeX: A Document Preparation System}, 2nd ed.,
Addison-Wesley, 1994.

\bibitem{okumura2020}
奥村晴彦・黒木裕介,
『\LaTeXe 美文書作成入門』第 8 版,
技術評論社, 2020.

\end{thebibliography}

\end{document}

編譯流程​

基本(platex + dvipdfmx)​

為了正確解決交叉參照與目錄,請先執行 platex 兩次,然後用 dvipdfmx 轉成 PDF。

platex -interaction=nonstopmode -kanji=utf8 document.tex
platex -interaction=nonstopmode -kanji=utf8 document.tex
dvipdfmx document.dvi

ptex2pdf​

也可以用將 platex + dvipdfmx 二步驟合併成一個指令的 ptex2pdf。

基本指令​

ptex2pdf -l -ot "-kanji=utf8 -interaction=nonstopmode" document.tex
選項含意
-l使用以 latex 為基礎的引擎(platex)
-ot "..."傳給 platex 的選項
-kanji=utf8指定輸入編碼為 UTF-8
-interaction=nonstopmode發生錯誤時不停止繼續處理

步驟​

  1. 執行 ptex2pdf 兩次(為了解決交叉參照與目錄)

    ptex2pdf -l -ot "-kanji=utf8 -interaction=nonstopmode" document.tex
    ptex2pdf -l -ot "-kanji=utf8 -interaction=nonstopmode" document.tex
  2. 確認結果

    • 成功:會產生 document.pdf
    • 發生錯誤:檢查 .log 中以 ! 開頭的行及其前後 3 行
    • 只有警告:檢查 Overfull/Underfull hbox、未定義參照等
  3. 若需要 BibTeX(當有 .bib 檔或包含 \bibliography 指令時)

    ptex2pdf -l -ot "-kanji=utf8 -interaction=nonstopmode" document.tex
    bibtex document
    ptex2pdf -l -ot "-kanji=utf8 -interaction=nonstopmode" document.tex
    ptex2pdf -l -ot "-kanji=utf8 -interaction=nonstopmode" document.tex

    在執行 bibtex 後再次執行 ptex2pdf 兩次是為了解決參考文獻清單與內文引用編號的交叉參照。

常見錯誤與處理​

Undefined control sequence​

! Undefined control sequence.
l.42 \somecommand

代表使用了未定義的指令。通常是忘了載入某個套件或是打錯字造成的。

Missing $ inserted​

! Missing $ inserted.

表示在數學模式外使用了 _(下標)或 ^(上標)等數學符號。請用 $...$ 將其包起來。

File not found​

! LaTeX Error: File `image.png' not found.

表示 \includegraphics 指定的檔案路徑錯誤。請確認相對於 .tex 的路徑是否正確。

Overfull \hbox​

Overfull \hbox (12.3pt too wide) in paragraph at lines 55--60

這是警告不是錯誤。表示行超出指定寬度。常見原因為長 URL 或長英文字,通常可用 \allowbreak 或用 \url{}(url 套件)來解決。

檢查日誌​

編譯後產生的 .log 檔會記錄錯誤與警告的詳細資訊。錯誤行通常以 ! 開頭,警告則包含 Warning 字樣。

grep -n "^!" document.log # 抽出錯誤行
grep -n "Warning" document.log # 抽出警告行

刪除中間檔案​

編譯會產生許多中間檔。若想保留 PDF 並清理其他檔案,可執行下列指令。

rm -f document.aux document.log document.dvi \
document.toc document.lof document.lot \
document.out document.bbl document.blg \
document.synctex.gz

若要全部刪除(包含 PDF),請再加上 .pdf。

在 Linux 安裝 TeX Live 2026

將使用 ISO 映像在 Linux(RHEL 系)上安裝 TeX Live 2026 的步驟整理如下,適用於 RHEL 系統。

前置條件​

  • 具有 sudo 權限
  • 磁碟空間至少 10 GB(ISO 約 6.4 GB + 安裝目標約 8 GB)
  • 有網路連線

Step 1: 下載 ISO 映像檔​

從理化學研究所的鏡像站下載 ISO。

cd
curl -C - -O --progress-bar https://ftp.riken.jp/CTAN/systems/texlive/Images/texlive2026.iso

-C - 是在下載中斷時繼續下載的選項。

下載完成後,確認檔案大小(約 6.4 GiB):

ls -lh ~/texlive2026.iso

Step 2: 掛載 ISO 映像​

建立掛載點,並將 ISO 以 loop 裝置掛載為唯讀:

sudo mkdir -p /mnt/texlive
sudo mount -o loop,ro ~/texlive2026.iso /mnt/texlive

確認是否掛載:

ls /mnt/texlive

出現如下檔案即可視為成功:

install-tl archive tlpkg README ...

Step 3: 執行安裝程式​

sudo /mnt/texlive/install-tl

會啟動文字介面互動選單。

主要操作按鍵​

鍵操作
S選擇安裝方案
D變更安裝目錄
I開始安裝
Q結束(取消)

建議設定​

  • 方案: scheme-full(全部套件,包含日本語 LaTeX 所需的 collection-langjapanese)
  • 安裝路徑: /usr/local/texlive/2026(預設)

確認設定後輸入 I 開始安裝。安裝需時數十分鐘。

Step 4: 設定 PATH​

將 TeX Live 的執行檔路徑加入 ~/.bashrc:

echo 'export PATH="/usr/local/texlive/2026/bin/x86_64-linux:$PATH"' >> ~/.bashrc
source ~/.bashrc

Step 5: 修正語系 (RHEL 系)​

在 RHEL 系統若未設定 locale,執行 lualatex 時會發生錯誤。請執行:

sudo dnf install -y glibc-langpack-en

另外,在 shell 啟動時設定 locale:

echo 'export LANG=C.UTF-8' >> ~/.bashrc
source ~/.bashrc

Step 6: 檢查是否可正常執行​

確認各指令的版本:

tex --version
lualatex --version
platex --version

預期輸出範例:

TeX 3.141592653 (TeX Live 2026)
LuaHBTeX, Version 1.24.0 (TeX Live 2026)
e-upTeX 3.141592653-p4.1.2-u2.02 (TeX Live 2026)

Step 7: 測試日文編譯​

建立測試檔案:

cat > /tmp/test.tex << 'EOF'
\documentclass{jlreq}
\begin{document}
日本語のテスト。TeX Live 2026 による日本語組版のサンプルです。
\end{document}
EOF

編譯:

cd /tmp && lualatex test.tex

若生成 test.pdf 即為成功。

Step 8: 清理(可選)​

安裝完成後,可刪除 ISO 與掛載點:

sudo umount /mnt/texlive
rm ~/texlive2026.iso

鏡像站列表​

若下載速度慢,可嘗試其他鏡像站:

鏡像站URL
理化學研究所(建議)https://ftp.riken.jp/CTAN/systems/texlive/Images/
JAISThttps://ftp.jaist.ac.jp/pub/CTAN/systems/texlive/Images/
山形大學https://ftp.yz.yamagata-u.ac.jp/pub/CTAN/systems/texlive/Images/
CTAN 鏡像https://mirror.ctan.org/systems/texlive/Images/

在 WSL 2 上安裝 Rocky Linux 8.10

下載 WSL 2 映像檔​

https://dl.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-Container-Base.latest.x86_64.tar.xz

從這裡下載。

參考: https://docs.rockylinux.org/8/guides/interoperability/import_rocky_to_wsl/

解壓映像檔​

將 tar.xz 解壓成 tar 檔。轉成 tar 後即可匯入到 WSL2。

cd ~/Downloads

xz -d Rocky-8-Container-Base.latest.x86_64.tar.xz

※Windows 上預裝的 bsdtar 無法解壓此檔。
※若沒有 xz 指令,可在 Cygwin64 安裝,或使用其他 WSL 發行版來解壓。

匯入映像至 WSL2​

將映像匯入到 WSL2。

wsl --import RockyLinux-8.10 $HOME .\Rocky-8-Container-Base.latest.x86_64.tar --version 2

確認映像​

wsl -l -v

新增使用者並設定預設使用者​

以使用者名稱 hikari 為例:

wsl -d RockyLinux-8.10 -u root -- dnf install sudo passwd -y

wsl -d RockyLinux-8.10 -u root -- adduser hikari

wsl -d RockyLinux-8.10 -u root -- passwd -d hikari

wsl -d RockyLinux-8.10 -u root -- usermod -aG wheel hikari

wsl -d RockyLinux-8.10 -u root -- sed -i 's/^# %wheel/%wheel/' /etc/sudoers

wsl -d RockyLinux-8.10 -u root -- echo -e "[user]\\ndefault=hikari" `| tee -a /etc/wsl.conf

啟動映像​

wsl -d RockyLinux-8.10