012#构建shelll脚本库
-
sourcing 功能
- 使用source、点号(.) 或 exec读入脚本,可使脚本成为了主运行进程
- 脚本中的命令就好像是直接在当前shell中输入的一样(父shell)
-
提取前面涉及的函数及全局变量或数组,将其合并到一个文件
library.sh
中
View Code
#!/usr/bin/env bash
validint(){
number=$1
min=$2
max=$3
# 空值检测
if [ -z $number ]; then
echo "You didn't input anything." >&2
return 1
fi
# 负数符号检测
if [ "${number%${number#?}}" = "-" ]; then
num="${number#?}"
else
num="${number}"
fi
# 检查除负数符号后的数字是否是整数
nodigits=$(echo $num | sed 's/[[:digit:]]//g')
if [ ! -z "$nodigits" ]; then
echo "Invalid number format. Only digits, no commas, spaces, etc." >&2
return 1
fi
# 判断输入值是否小于指定最小值
if [ ! -z $min ]; then
if [ $number -lt $min ]; then
echo "You value is too small. the smallest value is $min" >&2
return 1
fi
fi
# 判断输入值是否大于指定最大值
if [ ! -z $max ]; then
if [ $number -gt $max ]; then
echo "You value is too big. the largest value is $max" >&2
return 1
fi
fi
return 0
}
inpath() {
cmd=$1
ourpath=$2
result=1
oldIFS=$IFS
IFS=":"
for dir in $ourpath; do
if [ -x $dir/$cmd ]; then
result=0
fi
done
IFS=$oldIFS
return $result
}
checkForCmdInPath() {
var=$1
if [ $var != "" ]; then
if [ ${var%${var#?}} = "/" ]; then
if [ ! -x $var ]; then
return 1
fi
elif ! inpath $var "$PATH"; then
return 2
fi
fi
}
# 判断给定月份的有效天数
exceedsDaysInMonth()
{
case $(echo $1 | tr '[:upper:]' '[:lower:]') in
jan* ) days=31 ;;
feb* ) days=28 ;;
mar* ) days=31 ;;
apr* ) days=30 ;;
may* ) days=31 ;;
jun* ) days=30 ;;
jul* ) days=31 ;;
aug* ) days=31 ;;
sep* ) days=30 ;;
oct* ) days=31 ;;
nov* ) days=30 ;;
dec* ) days=31 ;;
* ) echo "$0: Unkown month name $1" >&2
exit 1
esac
# 判断天数是否有效,有效返回0,无效返回1
if [ $2 -lt 1 -o $2 -gt $days ]; then
return 1
else
return 0
fi
}
# 验证闰年
isLeapYear()
{
year=$1
if [ "$((year%4))" -eq 0 -a "$((year%100))" -ne 0 ]; then
return 0
elif [ "$((year%400))" -eq 0 ]; then
return 0
else
return 1
fi
}
# 规范日期
normaldate()
{
newdate="$(normdate "$@")"
if [ $? -eq 1 ]; then
exit 1
fi
# 拆分规范后的日期格式,检验其合法有效性
month="$(echo $newdate | cut -d\ -f1)"
day="$(echo $newdate | cut -d\ -f2)"
year="$(echo $newdate | cut -d\ -f3)"
msg1="$0: $3 is not a leap year, so Feb doesn't have 29 days."
msg2="$0: bad day value: $month does't have $2 days."
if ! exceedsDaysInMonth $month $2; then
if [ "$month" = "Feb" -a $2 -eq 29 ]; then
if ! isLeapYear $3; then
echo $msg1 >&2
exit 1
fi
else
echo $msg2 >&2
exit 1
fi
fi
}
# echon()
echon()
{
echo -e "$*" | awk '{printf("%s", $0)}'
}
# initializeANSI()
initializeANSI()
{
esc="\e"
# 前景色:
blackf="${esc}[30m";
redf="${esc}[31m";
greenf="${esc}[32m";
yellowf="${esc}[33m";
bluef="${esc}[34m";
purplef="${esc}[35m";
cyanf="${esc}[36m";
whitef="${esc}[37m";
# 背景色:
blackb="${esc}[40m";
redb="${esc}[41m";
greenb="${esc}[42m";
yellowb="${esc}[43m";
blueb="${esc}[44m";
purpleb="${esc}[45m";
cyanb="${esc}[46m";
whiteb="${esc}[47m";
# 粗体、斜体、下划线以及样式切换:
boldon="${esc}[1m";
boldoff="${esc}[22m";
italicson="${esc}[3m";
italicsoff="${esc}[23m";
ulon="${esc}[4m";
uloff="${esc}[24m";
invon="${esc}[7m"; # 反色,前景色与背景色互换
invoff="${esc}[27m";
reset="${esc}[0m"
}
- 创建测试脚本
library-test
读入库文件library.sh,并调用其中的函数
View Code
#!/bin/bash
# library-test
# 读入文件library.sh
. library.sh
initializeANSI
echon "First off, do you have echo in you path?(1=yes, 2=no)"
read answer
while ! validint $answer 1 2; do
echon "${boldon}Try again${boldoff}. Do you have echo "
echon "in you path?(1=yes, 2=no) "
read answer
done
if ! checkForCmdInPath "echo"; then
echo "Nope, can't find the echo command."
else
echo "The echo comman is in the PATH."
fi
echo ""
echon "Enter a year you think might be a leep year:"
read year
while ! validint $year 1 9999; do
echon "Please enter a year in the ${boldon}correct${bolldoff}format: "
done
if isLeapYear $year; then
echo -e "${greenf}You're right! ${year} is a leap year.${reset}"
else
echo -e "${redf}Nope, that is not a leap year.${reset}"
fi
exit 0
-
验证结果:
*** 你必须十分努力,才能看起来毫不费力 ***