0

Hướng dẫn truyền biến động từ Terminal vào Makefile

Makefile đôi khi làm giảm đi sự linh hoạt. Ví dụ: bạn muốn tạo một Kafka topic mới với tên tùy ý, build một Docker image với tag phiên bản khác nhau, hay chạy ứng dụng Go ở một môi trường cụ thể.

Thay vì phải mở file cấu hình ra sửa liên tục, bạn hoàn toàn có thể truyền trực tiếp các giá trị này từ terminal vào trong lúc chạy lệnh. Dưới đây là 3 phương pháp phổ biến và hiệu quả nhất.


1. Truyền trực tiếp qua tham số dòng lệnh (Command-line Variables)

Đây là cách cơ bản và được sử dụng nhiều nhất. Bạn sẽ định nghĩa một biến trong Makefile với giá trị mặc định, và ghi đè nó từ terminal khi gọi lệnh make.

Sử dụng toán tử ?= để gán giá trị mặc định. Nếu từ terminal có truyền biến vào, Makefile sẽ bỏ qua giá trị mặc định và ưu tiên dùng giá trị từ terminal.

Trong file Makefile:

# Gán giá trị mặc định nếu terminal không truyền vào
TOPIC_NAME ?= default_topic
PARTITIONS ?= 1

.PHONY: create-topic
create-topic:
	@echo "Đang tạo topic: $(TOPIC_NAME) với $(PARTITIONS) partitions..."
	# Ví dụ thực tế:
	# docker compose exec kafka /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic $(TOPIC_NAME) --partitions $(PARTITIONS)

Cách gọi từ terminal:

make create-topic TOPIC_NAME=order_events PARTITIONS=3

Kết quả in ra:

Đang tạo topic: order_events với 3 partitions...

2. Sử dụng Biến môi trường (Environment Variables)

Makefile có khả năng tự động nhận diện các biến môi trường của hệ điều hành. Cách này cực kỳ hữu ích khi bạn triển khai trên các hệ thống CI/CD hoặc cần áp dụng một cấu hình chung cho nhiều lệnh khác nhau cùng lúc.

Trong file Makefile:

ENV ?= local

.PHONY: build
build:
	@echo "Đang build ứng dụng Go cho môi trường: $(ENV)"
	go build -tags $(ENV) -o ./bin/app ./cmd/main.go

Cách gọi từ terminal:

Bạn có thể truyền biến ngay phía trước lệnh make:

ENV=production make build

Hoặc export ra hệ thống trước rồi mới chạy lệnh:

export ENV=staging
make build

3. Hỏi và chờ người dùng nhập (Interactive Input)

Nếu bạn muốn tạo một kịch bản tương tác (script dừng lại và chờ người gõ nội dung vào), bạn có thể tận dụng lệnh read của bash (shell mặc định chạy bên dưới Makefile). Cách này rất an toàn cho các tác vụ nguy hiểm như xóa dữ liệu.

Trong file Makefile:

.PHONY: drop-db
drop-db:
	@read -p "Bạn có chắc chắn muốn xóa sạch Database không? (y/N): " ans; \
	if [ "$$ans" = "y" ] || [ "$$ans" = "Y" ]; then \
		echo "Tiến hành xóa Database..."; \
		# docker compose down -v; \
	else \
		echo "Đã hủy thao tác."; \
	fi

(Lưu ý: Bạn phải dùng $$ thay vì $ để gọi biến ans trong vòng lặp bash của Makefile).

Cách gọi từ terminal:

Chỉ cần gõ lệnh make drop-db, terminal sẽ tạm dừng và hiển thị dấu nhắc chờ bạn nhập y hoặc N.


💡 Bảng tổng hợp thứ tự ưu tiên

Khi bạn kết hợp nhiều cách, Makefile sẽ lấy giá trị theo thứ tự ưu tiên từ cao xuống thấp như sau:

  1. Biến truyền trực tiếp lúc gọi lệnh (make VAR=value)
  2. Biến môi trường hệ thống (ENV=value make)
  3. Biến định nghĩa mặc định bên trong file Makefile (VAR ?= value)

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí