Ngừng chờ đợi Grep: Hướng dẫn thực tế về Fzf và Ripgrep cho môi trường Production

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Vấn đề: Khi các công cụ tiêu chuẩn gặp giới hạn

Tôi từng lãng phí nhiều phút mỗi ngày để chờ grep quét qua các file log khổng lồ. Trong nhiều năm, quy trình làm việc của tôi phụ thuộc vào bộ đôi cổ điển findgrep. Chúng đáng tin cậy và có sẵn ở mọi nơi, nhưng lại gặp khó khăn khi dự án mở rộng quy mô. Khi tôi bắt đầu quản lý hơn 10 VPS với các file log lên đến hàng gigabyte, những công cụ cũ kỹ này bắt đầu trở thành “nút thắt cổ chai” (nếu bạn làm việc với log hệ thống, đừng bỏ qua bài viết về phân tích log Linux hiện đại với Journalctl).

Sáu tháng trước, tôi đã thay thế bộ công cụ tìm kiếm của mình bằng fzf (một công cụ tìm kiếm mờ – fuzzy finder trên dòng lệnh) và ripgrep (một công cụ tìm kiếm hiệu suất cao). Ripgrep (rg) được viết bằng Rust và liên tục vượt mặt GNU grep nhờ tận dụng khả năng xử lý song song. Trong khi đó, fzf thêm một lớp tương tác cho phép bạn lọc kết quả ngay khi đang gõ. Sự kết hợp này không chỉ giúp tiết kiệm vài giây tìm kiếm; nó thay đổi hoàn toàn cách bạn điều hướng hệ thống tệp (filesystem).

Ưu điểm thực sự nằm ở logic “fuzzy” (tìm kiếm mờ) của fzf. Bạn không còn cần phải nhớ chính xác đường dẫn file. Chỉ cần gõ vài ký tự rời rạc, fzf sẽ thu hẹp phạm vi giữa hàng nghìn file ngay lập tức. Bằng cách dẫn (pipe) đầu ra của ripgrep vào fzf, bạn sẽ tạo ra một công cụ tìm kiếm tùy chỉnh được thiết kế riêng cho terminal của mình, tương tự như cách quản trị viên Linux sử dụng Tmux để quản lý phiên làm việc.

Cài đặt: Trang bị cho môi trường của bạn

Hầu hết các bản phân phối Linux hiện đại đều bao gồm các công cụ này trong kho lưu trữ (repository) chính thức. Tuy nhiên, tôi khuyên bạn nên kiểm tra phiên bản để đảm bảo có quyền truy cập vào các tính năng mới nhất.

1. Cài đặt Ripgrep (rg)

Trên Ubuntu Server hoặc Debian (20.04+), sử dụng apt:

sudo apt update
sudo apt install ripgrep

Cho hệ thống Fedora hoặc RHEL:

sudo dnf install ripgrep

Nếu bạn đang dùng một bản phân phối cũ hơn, bạn có thể tải file thực thi (binary) trực tiếp từ GitHub hoặc sử dụng Cargo:

cargo install ripgrep

2. Cài đặt Fzf

Mặc dù apt vẫn hoạt động tốt, tôi thích phương pháp cài đặt qua git hơn. Nó cung cấp phiên bản mới nhất và đơn giản hóa việc thiết lập các tiện ích mở rộng cho shell như tự động hoàn thành (auto-completion).

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

Chọn ‘Yes’ cho tất cả các câu hỏi trong quá trình cài đặt. Việc này sẽ tự động cập nhật file .bashrc hoặc .zshrc của bạn để kích hoạt các phím tắt thiết yếu như CTRL-T (tìm file) và CTRL-R (tìm kiếm lịch sử lệnh).

Cấu hình: Kết nối các thành phần

Cài đặt thô chỉ là bước khởi đầu. Theo mặc định, fzf sử dụng lệnh find tiêu chuẩn để liệt kê các file. Chúng ta có thể làm tốt hơn thế. Chúng ta muốn fzf sử dụng ripgrep vì nó nhanh hơn và tự động tuân thủ các quy tắc trong .gitignore của bạn.

Cấu hình Fzf để sử dụng Ripgrep

Thêm các dòng sau vào file ~/.bashrc hoặc ~/.zshrc của bạn:

# Sử dụng ripgrep để tìm file nhằm loại bỏ rác và dữ liệu git ẩn
export FZF_DEFAULT_COMMAND='rg --files --hidden --glob "!.git/*"'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"

Thiết lập này đảm bảo rằng khi bạn nhấn CTRL-T, bạn sẽ không thấy hàng nghìn file nội bộ của .git. Tuy nhiên, nó vẫn sẽ hiển thị các file ẩn quan trọng như .env hoặc .htaccess.

Một hàm “Tìm kiếm và Mở” mạnh mẽ

Một trong những quy trình làm việc tôi sử dụng nhiều nhất là tìm kiếm một chuỗi ký tự cụ thể và mở file đó tại chính xác số dòng cần tìm. Hãy thêm hàm này vào cấu hình shell của bạn để tự động hóa việc đó:

# Tìm trong File (fif): Tìm kiếm văn bản và mở trong Vim tại đúng dòng
fif() {
  if [ ! "$#" -gt 0 ]; then return; fi
  rg --column --line-number --no-heading --color=always --smart-case -- "$1" | \
    fzf --ansi \
        --delimiter : \
        --preview 'bat --style=numbers --color=always --highlight-line {2} {1} 2>/dev/null || cat {1}' \
        --preview-window 'up,60%,border-bottom,+{2}+7/2' \
        --bind "enter:become(vim {1} +{2})"
}

Lưu ý: Hàm này sử dụng bat để xem trước (preview) với cú pháp được làm nổi bật. Nếu bạn không có nó, hàm sẽ quay về sử dụng cat.

Cải thiện giao diện người dùng (UI)

Giao diện mặc định của fzf hơi đơn điệu. Bạn có thể làm cho nó dễ đọc hơn bằng cách thêm viền và bố cục căn giữa:

export FZF_DEFAULT_OPTS='--height 45% --layout=reverse --border --color="border:#777777"'

Kiểm chứng: Đo lường hiệu quả

Sau khi tải lại shell (source ~/.bashrc), hãy kiểm tra tốc độ. Đi tới một thư mục dự án lớn — chẳng hạn như một monorepo hoặc mã nguồn nhân Linux — và nhấn CTRL-T. Bạn sẽ thấy nó phản hồi gần như tức thì (đây là bước cơ bản khi benchmarking máy chủ Linux của bạn).

So sánh hiệu năng

Con số luôn nói lên tất cả. Thử chạy hai lệnh này trong một thư mục có hơn 50.000 file:

# Lệnh find tiêu chuẩn
time find . -name "*.c" | wc -l

# Sử dụng Ripgrep
time rg --files -g "*.c" | wc -l

Trong các thử nghiệm của tôi trên một VPS sử dụng ổ cứng NVMe, find mất khoảng 1,2 giây, trong khi rg hoàn thành chỉ trong 0,08 giây. Đó là mức tăng hiệu suất gấp 15 lần, góp phần tối ưu hiệu suất máy chủ một cách đáng kể.

Mẹo thực tế và những sai lầm cần tránh

Fzf rất mạnh mẽ, nhưng việc dẫn (pipe) hàng triệu dòng vào nó vẫn có thể khiến giao diện bị lag. Nếu terminal của bạn bị treo, hãy kiểm tra htop. Thông thường, “nút thắt” nằm ở lệnh nguồn chưa được tối ưu chứ không phải do bản thân fzf.

Cũng cần lưu ý các file nhị phân (binary). Ripgrep mặc định bỏ qua chúng, nhưng nếu bạn ép nó tìm kiếm tất cả, bạn có thể nhận được một đống “rác” không thể đọc được trong cửa sổ xem trước. Luôn giữ --smart-case trong các bí danh (alias) của bạn. Tùy chọn này giúp tìm kiếm không phân biệt chữ hoa chữ thường trừ khi bạn gõ cụ thể một chữ cái in hoa.

Việc áp dụng các công cụ này giúp loại bỏ sự cản trở khi điều hướng trong một hệ thống tệp phức tạp. Sau sáu tháng sử dụng, tôi thấy gần như không thể quay lại môi trường shell tiêu chuẩn.

Share: