Skip to content

Amber 的初步使用

Published: at 00:00

前言

有些时候,需要编写一些 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 的官网。