LỗiNếu bạn đã từng thử chạy một Bash script viết cho Linux trên Mac, có lẽ bạn đã gặp phải rào cản này. Thay vì tính toán ngày tháng, terminal của bạn lại hiển thị một đoạn văn bản gây khó chịu:
date: illegal option -- d
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
Tại sao lỗi này xảy raVấn đề nằm ở nguồn gốc hệ điều hành. Các bản phân phối Linux như Ubuntu hay Debian sử dụng GNU Coreutils. Trong phiên bản date của GNU, cờ -d được dùng để phân tích các chuỗi như "yesterday" hoặc "30 days ago."
macOS thì khác. Nó dựa trên BSD, vốn sử dụng một phiên bản tiện ích date hoàn toàn khác. Trên Mac, cờ -d thực chất được dùng để thiết lập giá trị Giờ tiết kiệm ánh sáng ngày (Daylight Saving Time). Nếu bạn muốn tính toán ngày tháng bằng lệnh gốc của Mac, bạn phải sử dụng cờ -v. Vì cú pháp quá khác biệt, các script viết cho Linux hầu như luôn bị lỗi trên macOS.
Giải pháp 1: Cài đặt GNU Coreutils (Cách xử lý chuyên nghiệp)Cách sạch nhất để khắc phục là mang các công cụ GNU lên Mac của bạn. Điều này cho phép bạn chạy các lệnh kiểu Linux mà không cần viết lại toàn bộ thư viện script. Bạn có thể thực hiện việc này trong khoảng hai phút bằng Homebrew.
1. Cài đặt HomebrewNếu bạn chưa cài đặt Homebrew, hãy dán dòng này vào terminal để cài đặt trình quản lý gói này:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
2. Cài đặt CoreutilsTiếp theo, hãy cài đặt bộ tiện ích GNU. Gói này khá nhỏ—thường dưới 15MB—và cài đặt rất nhanh:
brew install coreutils
Sau khi cài đặt xong, phiên bản GNU của lệnh date sẽ có sẵn dưới tên gdate. Nó hoạt động hoàn toàn giống lệnh date trên Linux:
gdate -d "yesterday"
Giải pháp 2: Viết Script đa nền tảngBạn có chia sẻ script của mình với nhóm không? Không phải lúc nào bạn cũng có thể mặc định rằng mọi người đều đã cài đặt coreutils. Cách tiếp cận tốt hơn là thêm một đoạn kiểm tra logic nhỏ ở đầu script để phát hiện hệ điều hành và tự động chọn lệnh phù hợp.
Đoạn mã ví dụ:```
Kiểm tra xem có đang chạy trên macOS (Darwin) không
if [[ "$OSTYPE" == "darwin"* ]]; then if command -v gdate > /dev/null 2>&1; then DATE_CMD="gdate" else echo "Thiếu phụ thuộc 'coreutils' cần thiết. Cài đặt bằng: brew install coreutils" exit 1 fi else DATE_CMD="date" fi
Bây giờ sử dụng $DATE_CMD thay vì 'date'
$DATE_CMD -d "2024-01-01 + 5 days"
## Giải pháp 3: Sử dụng Alias (Bí danh)Nếu bạn chỉ muốn chạy các lệnh thủ công và không muốn gõ chữ 'g' mỗi lần, bạn có thể ánh xạ `date` thành `gdate` trong cấu hình shell của mình. Đây là một cách sửa lỗi cục bộ tuyệt vời cho quy trình làm việc cá nhân.
- Mở cấu hình Zsh của bạn: `nano ~/.zshrc`- Thêm dòng này vào cuối file: `alias date='gdate'`- Cập nhật lại shell: `source ~/.zshrc`**Lưu ý:** Alias này chỉ hoạt động trong terminal tương tác. Nó sẽ không sửa được các file `.sh` độc lập vì các shell script không kế thừa alias theo mặc định.
## Kiểm tra kết quảHãy đảm bảo mọi thứ đang hoạt động trơn tru. Thử tính toán một ngày cụ thể trong tương lai:
gdate -d "2024-12-25 + 1 year" +"%Y-%m-%d"
Nếu terminal trả về `2025-12-25`, bạn đã thành công. Bạn cũng có thể kiểm tra lại phiên bản để xác nhận mình đang dùng bộ công cụ GNU:
gdate --version
Dòng đầu tiên của kết quả sẽ có dạng như `date (GNU coreutils) 9.4`.
## Mẹo phòng tránh lỗi- **Chuẩn hóa bằng gdate:** Nếu nhóm của bạn sử dụng cả Mac và server Linux, hãy quy định sử dụng `gdate` trong tất cả các script và đưa `coreutils` vào tài liệu hướng dẫn thiết lập môi trường macOS.- **Cân nhắc sử dụng Python:** Đối với các logic ngày tháng phức tạp, hãy sử dụng một dòng lệnh Python. Module `datetime` của Python hoạt động giống hệt nhau trên mọi hệ điều hành, giúp bạn tránh hoàn toàn cơn đau đầu mang tên BSD vs. GNU.- **Kiểm tra các cờ (flags):** Trước khi chuyển một script lớn, hãy chạy `man date` trên Mac. Đây là cách nhanh nhất để thấy các cờ của BSD khác biệt thế nào so với những gì bạn thường dùng trên Linux.

