Tôi yêu bash, nó rất tiện dụng để viết những script nhỏ chạy tự động, đặc biệt là cho CI/CD. Tuy nhiên, thú thực không phải lúc nào tôi cũng nhớ hết syntax của bash, và tôi luôn mong muốn có một công cụ nào đó giúp tôi viết bash script một cách dễ dàng hơn. Cảm ơn trời, Amber đã xuất hiện. Trong bài viết này tôi muốn chia sẻ về Amber và cách nó đã khiến việc lập trình bash trở nên thú vị hơn.
Amber là gì?
Chắc chắn không phải tên của vợ ông thuyền trưởng nào đó, Amber được giới thiệu là một ngôn ngữ biên dịch được viết bằng rust, giúp biên dịch code sang bash. Theo như giới thiệu trên trang chủ:
Amber là ngôn ngữ lập trình được biên dịch thành Bash Script. Nó được thiết kế với cú pháp hiện đại, các tính năng an toàn, typesafe và các chức năng thiết thực mà Bash không thể cung cấp. Amber
Tóm cái v áy lại, Amber là một lớp bổ sung typesafe cho bash script. Nó giống như trường hợp của Typescript và Javascript vậy. Bạn có thể tìm hiểu kỹ hơn về syntax của Amber ở trang chủ.
Cài đặt Amber
-
Với MacOS/Linux, việc này rất đơn giản:
curl -s "https://raw.githubusercontent.com/Ph0enixKM/AmberNative/master/setup/install.sh" | bash -
Còn với Windows?
Chà, bạn không thể cài trực tiếp trên Win vì lý do rất đơn giản: Windows không hỗ trợ bash, nên việc cài Amber trên Win không mang ý nghĩa gì cả. Tuy nhiên, bạn có thể cài trên WSL (Windows Subsystem for Linux) hoặc sử dụng Docker. Có những lưu ý thêm cho việc cài đặt trên win, bạn hãy tham khảo trên trang chủ.
Sử dụng Amber
Trước tiên, nếu bạn sử dụng VsCode, hãy thêm extension này để làm việc với Amber dễ dàng hơn: Amber Language. Nếu bạn biết các công cụ nào hỗ trợ vim/Sublime/Zed, hãy chia sẻ với tôi nhé.
Làm quen với Amber khá đơn giản do syntax được dựa trên ECMA script.
// example.ab
let target = "my friend"
let message = "Hello, {target}! Want some Shawarma?"
let repeated_times = 3
// In ra câu chào
loop i in 0..repeated_times {
echo message
}
let age = 10
// If-else
if age < 18 {
echo "\nI want za spicy garlic!\n"
} else {
echo "\nI want za regular garlic!\n"
}
// array loop
let fruits = ["apple", "banana", "cherry", "date"]
echo "My favorite fruits are:"
loop fruit in fruits {
echo fruit
}
Để chạy script trên, sử dụng lệnh sau:
amber example.ab
Nó sẽ biên dịch code sang bash và chạy nó. Kết quả sẽ như sau:
Hello, my friend! Want some Shawarma?
Hello, my friend! Want some Shawarma?
Hello, my friend! Want some Shawarma?
I want za spicy garlic!
My favorite fruits are:
apple
banana
cherry
date
Điều tuyệt vời ở đây là amber hỗ trợ compile file sang bash script. Bạn có thể sử dụng output của nó để chạy trên bất kỳ môi trường unix nào.
amber input.ab output.sh
Thử với file ví dụ bên trên (amber example.ab example.sh), đây là file bash script được tạo ra:
__0_target="my friend";
__1_message="Hello, ${__0_target}! Want some Shawarma?";
__2_repeated_times=3;
for i in $(seq 0 $(echo ${__2_repeated_times} '-' 1 | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//'))
do
echo "${__1_message}"
done;
__3_age=10;
if [ $(echo ${__3_age} '<' 18 | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
echo "
I want za spicy garlic!
"
else
echo "
I want za regular garlic!
"
fi;
__AMBER_ARRAY_0=("apple" "banana" "cherry" "date");
__4_fruits=("${__AMBER_ARRAY_0[@]}");
echo "My favorite fruits are:";
for fruit in "${__4_fruits[@]}"
do
echo "${fruit}"
done
Bạn có thể chạy trực tiếp file trên vì trong quá trình biên dịch Amber đã tự động gán quyền execute cho nó. Thật tuyệt 🎉🎉!
Bỏ qua việc đặt tên biến, bạn có thể thấy cú pháp của Amber dễ đọc hiểu hơn so với bash rất nhiều. Điều này giúp bạn viết script nhanh hơn, dễ đọc hơn và dễ bảo trì hơn.
Tuy nhiên nếu tinh ý bạn có thể thấy Amber xử lý logic loop chưa tốt ở thời điểm hiện tại. Như ví dụ phía trên, Amber đã sử dụng:
if [ $(echo ${__3_age} '<' 18 | bc -l | sed '/\./ s/\.\{0,1\}0\{1,\}$//') != 0 ]; then
# execute logic
Syntax trên cồng kềnh cộng thêm sử dụng thư viện ngoài (bc). Chắc chắn điều này sẽ chậm và khó đọc hơn so với cách loop truyền thống ở dưới:
for ((i=0; i < repeated_times; i++)); do
# execute logic
done
Do vậy ở thời điểm hiện tại, nếu bạn sử dụng loop trong dự án của mình, bạn cần kiểm tra và viết lại bash script để cải thiện hiệu năng nếu cần thiết.
Tính năng nổi bật
Hỗ trợ typesafe
Tôi từng viết một script khá dài để deploy microservices lên k8s, dẫn đến việc không kiểm tra type khi gán giá trị cho biến. Tôi đã gán string cho một biến đáng nhẽ là int và thực hiện tính toán, kết quả là chạy sai và tôi đã mất khá nhiều thời gian để debug xem lỗi nằm ở đoạn nào.
Ở Amber, bạn không thể làm điều đó. Compiler sẽ báo lỗi khi bạn gán sai kiểu vào biến, ví dụ:
// test.ab
let int = 5
let string = "hi"
let composed = int + string
echo composed
Bạn sẽ gặp lỗi ngay thời điểm compile amber test.ab test.sh:
Điều này sẽ tránh cho bạn khỏi phiền phức về sau khi mà code base mở rộng. Với tất cả tính năng của typesafe, script của bạn sẽ dễ đọc và bảo trì hơn.
Handle exception dễ dàng hơn
Hãy thử xem xét trường hợp sau, khi thực hiện một hàm bị trả về lỗi sẽ gọi một hàm khác để xử lý:
#!/bin/bash
message="$(command_returns_error)"
# 'set -e' nếu muốn dừng chương trình
if [ $? -ne 0 ]; then
do_another_command
fi
# ...
Thành thực mà nói, cú pháp trên hơi khó để hiểu cho người maintain. Nếu bạn không biết [ $? -ne 0 ] là gì thì thật khó để hiểu được luồng của script. Cùng xem liệu Amber có xử lý tốt hơn không:
command_returns_error() failed {
do_another_command()
}
Gọn và dễ đọc hơn nhiều