前言
有些时候,需要编写一些 Bash 脚本辅助程序的执行。对于不经常写 Bash 脚本的人来说,对于Bash脚本不是特别熟悉的话,就总是有一些感觉到莫名其妙的错误,排查到最后可能发现在某个地方多了个空格导致的。Bash脚本很久远以前就存在了,跟现代一些开发语言的语法风格相差太大,因此让很多人对 Bash 脚本的开发有不舒服或抗拒的心情。本文介绍一个 Amber 语言,拥有类似于 Python 和 Rust 的现代语法,通过编写简单的 Amber 脚本,可以直接编译成复杂的 Bash 脚本。也就是说,我们可以用 Amber 间接编写成服务器上要运行的 Bash 脚本。废话不多说,show me the code,正文将直接显示5个例子和简要说明。
例子1
let date_list = ["2023-01-01", "2023-06-01", "2023-11-01"]
loop index, day in date_list {
// 测试输出日期
echo "The day is {day}"
}
例子2
// 导入标准函数
import { parse } from "std"
// 准备日期
let date_list = ["2023-01-01", "2023-02-01", "2023-06-01", "2023-11-01"]
loop index, day in date_list {
echo "===================================="
// 输出日期
echo "The day is {day}"
// 执行 date 命令获取到年份
let year = $date -d {day} +%Y$ failed {
echo "Error: Failed to fetch year"
}
echo "The year is {year}"
// 执行 date 命令获取到月份
let month = $date -d {day} +%m$ failed {
echo "Error: Failed to fetch month"
}
echo "The month is {month}"
// 把 Text 类型的 month 解析成 Num 类型
let month_num = parse(month) failed {
echo "Error: Month is not a number"
}
let next_month = month_num + 1
if next_month > 12 {
next_month = 1
}
// 把 Text 类型的 year 解析成 Num 类型
let year_next_month = parse(year) failed {
echo "Error: Year is not a number"
}
if next_month == 1 {
year_next_month += 1
}
// 执行命令获取到当月的最后一天
let last_day = $date -d "{year_next_month}-{next_month}-01 -1 day" +"%Y-%m-%d"$ failed {
echo "Error: Failed to fetch last day"
}
echo "The last day is {last_day}"
}
例子3
// 导入标准函数
import { parse } from "std"
// 准备日期
let date_list = ["2023-01-01", "2023-02-01", "2023-06-01", "2023-11-01"]
// 获取最后天的函数
fun get_last_day(year, month) {
let month_num = parse(month) failed {
echo "Error: Month is not a number"
}
let next_month = month_num + 1
if next_month > 12 {
next_month = 1
}
let year_next_month = parse(year) failed {
echo "Error: Year is not a number"
}
if next_month == 1 {
year_next_month += 1
}
let last_day = $date -d "{year_next_month}-{next_month}-01 -1 day" +"%Y-%m-%d"$ failed {
echo "Error: Failed to fetch last day"
}
return last_day
}
loop index, day in date_list {
echo "===================================="
echo "The day is {day}"
let year = $date -d {day} +%Y$ failed {
echo "Error: Failed to fetch year"
}
echo "The year is {year}"
let month = $date -d {day} +%m$ failed {
echo "Error: Failed to fetch month"
}
echo "The month is {month}"
// 调用函数
let last_day = get_last_day(year, month)
echo "The last day is {last_day}"
// 执行命令输出星期信息
$date -d {last_day} +"%u"$ failed {
echo "Error: date command error"
}
}
例子4
fun get_last_day(year, month) {
let next_month = month + 1
if next_month > 12 {
next_month = 1
}
let year_next_month = year
if next_month == 1 {
year_next_month += 1
}
let last_day = $date -d "{year_next_month}-{next_month}-01 -1 day" +"%Y-%m-%d"$ failed {
echo "Error: Failed to fetch last day"
}
return last_day
}
let year = 2023
// 遍历1月到12月
loop month in 1..13 {
echo "======================================="
let last_day = get_last_day(year, month)
echo "The last day is {last_day}"
$date -d {last_day} +"%u"$ failed {
echo "Error: date command error"
}
}
例子5
fun get_last_day(year, month) {
let next_month = month + 1
if next_month > 12 {
next_month = 1
}
let year_next_month = year
if next_month == 1 {
year_next_month += 1
}
let last_day = $date -d "{year_next_month}-{next_month}-01 -1 day" +"%Y-%m-%d"$ failed {
echo "Error: Failed to fetch last day"
}
return last_day
}
let year = 2023
// 生成月份列表,中间加入异常的一1用于测试
let month_list = 1..5 + [-1] + 5..13
echo month_list
loop month in month_list {
echo "======================================="
let last_day = get_last_day(year, month)
echo "The last day is {last_day}"
// 上一次命令的状态码,0表示成功
echo "status: {status}"
// 如果不成功就中断后续的执行
if status != 0 {
break
}
$date -d {last_day} +"%u"$ failed {
echo "Error: date command error"
}
}
运行和编译
# 以 exp_1.ab 为例
# 直接运行
amber ./exp_1.ab
# 编译成 Bash 脚本: exp_1.sh,用于服务器上运行
amber ./exp_1.ab ./exp_1.sh
总结
通过 Amber 语言的使用,我们可以大大简化 Bash 脚本的开发复杂难度和避免一些莫名其妙的问题。当然对于一些很熟悉 Bash 脚本的人来说,这个可能就是多此一举的事情。请自行衡量使用,更多的用法和介绍可以查看 amber-lang 的官网。