写了一个简单易用的 shell 框架(下篇)

Easy Bash是一个简单的Bash库,旨在使脚本编写更轻松。它提供了变量管理、颜色输出、日志记录、选项解析等功能。通过内置选项和自动帮助消息生成,可以轻松实现详细和检查模式运行,以及自动生成配置文件。此外,还提供了日期操作和通知功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Easy Bash

Easy Bash - a simple bash library to make scripting easier.
在这里插入图片描述

Easy Bash libraries

Vars

Global variables useful or used by libraries are stored here.

Below shows some examples.

Date and time vars

MONTH_STR: 202205
DATE_STR: 20220501
TIME_STR: 20220501_3_132939

Script vars

SCRIPT_DIR: /data/scripts/easybash/test
SCRIPT_FULL_NAME: test_vars.sh

logging vars

LOG_LEVEL: INFO
LOG_DIR: /data/scripts/easybash/test/logs/202205/20220501
LOG_FILE: /data/scripts/easybash/test/logs/202205/20220501/test_vars_20220501_3_132939.log

And logging color vars

export COLOR_TRACE="green"
export COLOR_DEBUG="cyan"
export COLOR_INFO="white"
export COLOR_WARN="yellow"
export COLOR_ERROR="red"
export COLOR_FATAL="red"

For more global variables, refer to lib/lib_vars.sh.

Color

Test color example script.

bash examples/test_color.sh

Colors and corresponding numbers:

(["black"]="0" ["red"]="1" ["green"]="2" ["yellow"]="3" ["blue"]="4" ["magenta"]="5" ["cyan"]="6" ["white"]="7")

echo with colors

在这里插入图片描述

echo colors functions
echo_red "echo_red"
echo_red_bold "echo_red_bold"
echo_green "echo_green"
echo_green_bold "echo_green_bold"
echo_yellow "echo_yellow"
echo_yellow_bold "echo_yellow_bold"
echo_blue "echo_blue"
echo_blue_bold "echo_blue_bold"
echo_magenta "echo_magenta"
echo_magenta_bold "echo_magenta_bold"
echo_cyan "echo_cyan"
echo_cyan_bold "echo_cyan_bold"
echo_white "echo_white"
echo_white_bold "echo_white_bold"

在这里插入图片描述

Echo colors with background.

echo_blue "echo_blue: foreground - blue, no background." "" "bold"
echo_blue "echo_blue: foreground - blue, background: yellow." "yellow" "bold"

在这里插入图片描述

echo_color

echo_color is called by echo_blue etc…

echo_color "echo_color: foreground - green, no background." "green" "" "bold"
echo_color "echo_color: foreground - green, background - red." "green" "red" "bold"

在这里插入图片描述

echo_color_by_num

echo_color_by_num is called by echo_color .

echo_color_by_num "echo_color_by_num: foreground - red, no background." "1" "" "bold"
echo_color_by_num "echo_color_by_num: foreground - red, background - blue." "1" "4" "bold"

在这里插入图片描述

Set colors

Set color for existing echos
set_color "green"
echo "set_color: foreground - green, no background."
echo "You can echo lines as usual."
echo "So that you can easilly set color for existing echos."
echo "Or set the same color for mulitple lines."
echo "reset_color"
reset_color

在这里插入图片描述

set_color "green" "" "bold"
echo "set_color foreground - green bold, no background."
echo "You can echo lines as usual."
echo "So that you can easilly set color for existing echos."
echo "Or set the same color for mulitple lines."
echo "reset_color"
reset_color

在这里插入图片描述

Set color with background in loop
declare -a la_str
la_str+=("set_color foreground - green, background - red.")
la_str+=("You can echo lines as usual.")
la_str+=("So that you can easilly set color for existing echos.")
la_str+=("Or set the same color for mulitple lines.")
la_str+=("reset_color")
for str_value in "${la_str[@]}"; do
  set_color "green" "red"
  echo "${str_value}${COLOR_RESET}"
done

在这里插入图片描述

Logging

By default, the LOG_LEVEL is INFO which will not print trace or debug messages.

You can update lib/lib_vars.sh or add option -v to set LOG_LEVEL to TRACE to get more messsages.

Test logging example script.

bash examples/test_logging.sh -v
log_trace "This is a trace message."
log_debug "This is a debug message."
log_info "This is a info message."
log_warning "This is a warning message."
log_error "This is a warning message."
log_fatal "This is a fatal message."

在这里插入图片描述

Parse

Take following script for example.

cd easybash/echo_dates
cat echo_dates.sh
#!/usr/bin/env bash
################################################################################
#
# Author: Alvin
# License: MIT
# GitHub: https://github.com/dbadaily/easybash
#
# echo dates
################################################################################

VERSION_STR="1.0.0"

current_dir="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

lib_dir="$(dirname "${current_dir}")"

source "${lib_dir}/lib/easybash.sh"

add_main_options() {
  ## custom options
  # add your options here
  add_options "s:" "start-date:" "START_DATE" "Y" "start date"
  add_options "e:" "end-date:" "END_DATE" "Y" "end date"

  ## common options
  # 1. options like m: or emails: can be changed
  # 2. variable names like RECIPIENTS are NOT expected to be changed as they are used in libraries
  add_options "m:" "email:" "RECIPIENTS" "N" "emails(separated by space) to receive notifications"
  add_options "S" "success-notification" "SUCCESS_NOTIFICATION_IND" "N" "indication whether to send success notifications"
  add_options "C" "check" "CHECK_MODE" "N" "don't make any changes"
  add_options "G" "generate-config" "GEN_CONFIG" "N" "generate config file if not exists"
  add_options "w" "write-values" "WRITE_VALUES" "N" "used together with -G, write values provided by command options to config file"
  add_options "H" "help" "HELP" "N" "show this help"
  add_options "V" "version" "VERSION" "N" "output version information"
  add_options "v" "verbose" "VERBOSE" "N" "verbose mode"
}

# custom function
echo_dates() {
  local lv_start_date="$1"
  local lv_end_date="$2"
  local lv_msg="Work between ${lv_start_date} and ${lv_end_date} is done."
  while [[ "${lv_start_date}" -le "${lv_end_date}" ]]; do
    echo_blue_bold "Processing for date ${lv_start_date}"
    log_trace "Work for date ${lv_start_date} done."
    lv_start_date=$(date -d "${lv_start_date} + 1 days" +'%Y%m%d')
  done
  send_msg "${lv_msg}"
}

main() {
  add_main_options
  parse_args "$@"

  # add your logic here
  if [[ "$CHECK_MODE" != "Y" ]]; then
    echo_dates "${START_DATE}" "${END_DATE}"
  elif [[ "$CHECK_MODE" == "Y" ]]; then
    log_warning "CHECK MODE. Skip echoing dates."
  fi
}

main "$@"

Easy way to add options

Options can be added as below.

add_main_options() {
  ## custom options
  # add your options here
  add_options "s:" "start-date:" "START_DATE" "Y" "start date"
  ...
}
  1. The short option is s:

  2. The long option is start-date:

  3. It will create global variable START_DATE and assign command line option value to it

  4. "Y" indicates it is a required parameter

  5. "start date" is the option description

Automatic parsing and assignment

Parsing and variable assignment can be done easily using only one line code:

parse_args "$@"

All options will be automatically parsed by getopt.

# bash echo_dates.sh -s
getopt: option requires an argument -- 's'
# bash echo_dates.sh -f
getopt: invalid option -- 'f'

It will create global variables for every option.

And assignments are done automatically, so that you can reference them easily.

bash echo_dates.sh -s 20220101 -e 20220107 -v
[2022-05-01 08:30:01 TRACE] [parse_args] lv_valid_args: ' -s '20220101' -e '20220107' -v --'
[2022-05-01 08:30:01 DEBUG] [parse_args] START_DATE=20220101
[2022-05-01 08:30:01 DEBUG] [parse_args] END_DATE=20220107
[2022-05-01 08:30:01 DEBUG] [parse_args] VERBOSE=Y

Mixed short and long options

You can use mixed short and long options.

bash echo_dates.sh --start-date 20220101 -e 20220107 -v

Generate help message automatically

It will generate help message automatically based on the options and descriptions added.

bash echo_dates.sh -H

在这里插入图片描述

Built-in options

Common options are suggested to be added to utilize various functionalaties which will be introduced further more.

For the common options,

  1. You can change both short or long option names, e.g. m: or emails: can be changed
  2. All common variable names are used in easybash libraries and their names are NOT expected to be changed unless you update all referrenced variables accordingly.
add_main_options() {
  ## custom options
  # add your options here
  ...

  ## common options
  # 1. options like m: or emails: can be changed
  # 2. variable names like RECIPIENTS are NOT expected to be changed as they are used in libraries
  add_options "m:" "email:" "RECIPIENTS" "N" "emails(separated by space) to receive notifications"
  add_options "S" "success-notification" "SUCCESS_NOTIFICATION_IND" "N" "indication whether to send success notifications"
  add_options "C" "check" "CHECK_MODE" "N" "don't make any changes"
  add_options "G" "generate-config" "GEN_CONFIG" "N" "generate config file if not exists"
  add_options "w" "write-values" "WRITE_VALUES" "N" "used together with -G, write values provided by command options to config file"
  add_options "H" "help" "HELP" "N" "show this help"
  add_options "V" "version" "VERSION" "N" "output version information"
  add_options "v" "verbose" "VERBOSE" "N" "verbose mode"
}

Run in verbose mode

By default, the LOG_LEVEL is INFO.

You can always add option -v to reset LOG_LEVEL to TRACE to debug or get more detailed information.

bash echo_dates.sh -s 20220101 -e 20220107 -v

在这里插入图片描述

Run in check mode

-C is a super helpful option borrowed from ansible to indicate check mode or dry run mode.

You are encouraged to implement check logic in your codes and always run in check mode first so that you can double check to avoid unnecessary incidents.

if [[ "$CHECK_MODE" != "Y" ]]; then
  echo_dates "${START_DATE}" "${END_DATE}"
elif [[ "$CHECK_MODE" == "Y" ]]; then
  log_warning "CHECK MODE. Skip echoing dates."
fi
bash echo_dates.sh -s 20220101 -e 20220107 -v -C

在这里插入图片描述

Check required parameters

getopt doesn’t provide a way to check whether one option is required or not.

Yet it is helpful to check mandatory parameters first.

Parameter "Y" below indicates it is a required parameter.

add_options "s:" "start-date:" "START_DATE" "Y" "start date"

Better run in check mode so that it makes no changes.

Run without all required options, it will:

  1. give warning hints about all remaining required options
  2. give a fatal message
  3. exit after the fatal message
bash echo_dates.sh -v -C

在这里插入图片描述

Run with one parameter.

bash echo_dates.sh -s 20220101 -v -C

在这里插入图片描述

Generate config file

When there are too many parameters, it might be better to use a config file.

Write the config file yourself ?

Just use -G option to generate a config file for you based on the options specified.

By default, a config file named config.sh will be created in the same folder as the script.

And the config file will be sourced if it exists.

bash echo_dates.sh -s 20220101 -e 20220107 -v -G

在这里插入图片描述

Check the contents of the config file.

cat config.sh
# start date
START_DATE=""

# end date
END_DATE=""

...

During development, you might add more options.

It will save the old config file once you generate again.
在这里插入图片描述

Generate config file with values

Generating a config file with empty values is not enough, you need to set the values automatically.

Combine options -G and -w together, it will generate config file with parameters assigned.

bash echo_dates.sh -s 20220101 -e 20220107 -v -G -w

在这里插入图片描述

cat config.sh
# start date
START_DATE="20220101"

# end date
END_DATE="20220107"

...

After having generated config file with variables assigned, you can run the script without parameters.

bash echo_dates.sh -v

在这里插入图片描述

Overwrite config file variables

While all the variables are stored in a config file, you might need to update one or more variables in some scenarios.

You can also pass some parameters via options. Variables in config file will be overwritten by options.

bash echo_dates.sh -v -e 20220103

在这里插入图片描述

Notification

You can send messages using send_msg as below to send notification so that you are informed timely.

It would be very helpful if you need to keep an eye on the process of the script running.

Send only a message or subject of email:

send_msg "${lv_subject}"

Send a message and details:

send_msg "${lv_subject}" "${lv_body}"

Email can be specified by -m .

bash echo_dates.sh -s 20220101 -e 20220107 -m "alvin@dbadaily.com"

If RECIPIENTS is not provided via options nor config file, there will a warning message and no messages will be sent.

[2022-05-01 11:35:25 WARNING] RECIPIENTS is not set or empty. option -m RECIPIENTS or --email=RECIPIENTS might be set.

send_msg is prefered over send_email .

The former easily enables to turn to other efficient ways of notification, e.g. IM.

As you can see below, send_msg calls send_email which might be overwritten.

send_email() {
  ...
    echo "${lv_body}" | mail -s "${lv_subject}" "${lv_recipient}"
  ...
}

send_msg() {
  ...
    send_email "${RECIPIENTS}" "${lv_subject}" "${lv_body}"
  ...
}

Date

Date range is helpful in scenarios like:

  1. You need to delete data of some date range
  2. You need to dump or achive data of some date range

And there are several ways to specify data range.

  1. By start date and end date
  2. By month
  3. By start date and days

With set_dates_by_args, you can easily set START_DATE and END_DATE for all above three cases.

To get all the days between START_DATE and END_DATE , there are also three ways:

  1. get_dates by START_DATE and END_DATE
lv_dates="$(get_dates "${START_DATE}" "${END_DATE}")"
print_dates "${lv_dates}"
  1. get_dates_by_args which internally uses START_DATE and END_DATE
lv_dates="$(get_dates_by_args)"
print_dates "${lv_dates}"
  1. loop_dates by START_DATE and END_DATE
loop_dates "${START_DATE}" "${END_DATE}"

Test date example script codes:

cat examples/test_date.sh
main() {
  add_main_options
  parse_args "$@"

  local lv_dates=""
  set_dates_by_args

  log_trace "calling get_dates with parameters START_DATE and END_DATE"
  lv_dates="$(get_dates "${START_DATE}" "${END_DATE}")"
  print_dates "${lv_dates}"

  log_trace "calling get_dates_by_args without parameters"
  lv_dates="$(get_dates_by_args)"
  print_dates "${lv_dates}"

  log_trace "calling loop_dates with parameter START_DATE and END_DATE"
  loop_dates "${START_DATE}" "${END_DATE}"
}

Get dates by start date and end date

bash examples/test_date.sh -s 20220101 -e 20220103 -v
[2022-05-01 08:01:20 DEBUG] [parse_args] START_DATE=20220101
[2022-05-01 08:01:20 DEBUG] [parse_args] END_DATE=20220103
[2022-05-01 08:01:20 DEBUG] [parse_args] VERBOSE=Y
[2022-05-01 08:01:20 TRACE] calling get_dates with parameters START_DATE and END_DATE
[2022-05-01 08:01:20 INFO] lv_date=20220101
[2022-05-01 08:01:20 INFO] lv_date=20220102
[2022-05-01 08:01:20 INFO] lv_date=20220103
[2022-05-01 08:01:20 TRACE] calling get_dates_by_args without parameters
[2022-05-01 08:01:20 INFO] lv_date=20220101
[2022-05-01 08:01:20 INFO] lv_date=20220102
[2022-05-01 08:01:20 INFO] lv_date=20220103
[2022-05-01 08:01:20 TRACE] calling loop_dates with parameter START_DATE and END_DATE
[2022-05-01 08:01:20 INFO] lv_start_date=20220101
[2022-05-01 08:01:20 INFO] lv_start_date=20220102
[2022-05-01 08:01:20 INFO] lv_start_date=20220103

Get dates by month

bash examples/test_date.sh -M 202201 -v

Get dates by start date and days

bash examples/test_date.sh -s 20220101 -d 3 -v

Conclusion

easybash helps you write simple, efficient and colorful scripts easily.

You no longer need to do the following manually:

  1. parse all the arguments manually
  2. set variables manually
  3. write help message manually
  4. write config file manually
  5. check whether all required parameters are set manually
  6. write logs manually

And you are able to do the following easily:

  1. add options easily
  2. parse options easily
  3. do dry run test easily
  4. write colorful logs easily
  5. write and show different levels of logs easily
  6. send messages easily

原文链接:
https://blog.csdn.net/DBADaily/article/details/124601034
您浏览的网址与此链接不一致的话,则为未授权的转载,为了更好的阅读体验,建议阅读原文。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值