linux sh : use local shell script library
发布日期:2021-06-30 22:17:03
浏览次数:2
分类:技术文章
本文共 16049 字,大约阅读时间需要 53 分钟。
前言
上一个实验,工程是一个500行的脚本。
已经感到维护性不好了。 假设工程的功能增加了,代码量增加到几千行以上,如何改善脚本工程的可维护性呢? 看了段书,说到可以采用引入本地脚本库。相当于c语言中的include头文件。 使用库包含后,做其他工程时,就有可以重用的代码库了。重构了一下,按照功能和逻辑,将主脚本中的代码下拉到脚本库中,改造完成后,看着清爽多了。
实验
# !/bin/bash# @file main.sh# @brief wrap a shell script functin to check user exist, # use array to pass output parameter, not use any global var# include other shell script. ./sh.const_define. ./sh.helper. ./sh.prog_version. ./sh.test_case. ./sh.file_opt_etc_passwd. ./sh.user_info# --------------------------------------------------------------------------------# do task# --------------------------------------------------------------------------------function func_do_task() { # test user exist and have home dir fuc_show_user_info "root" # user not exist, but have home dir fuc_show_user_info "dev" # user not exist and have not home dir fuc_show_user_info "user_not_exist"}# --------------------------------------------------------------------------------# main shell script# --------------------------------------------------------------------------------func_initfunc_show_titlefunc_show_prog_infofunc_show_os_info# func_test_casefunc_do_taskfunc_show_tailfunc_uinit
# !/bin/bash# @file sh.const_define# @brief define project's const valueIND_CHAR=-LINE10=${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}LINE80=${LINE10}${LINE10}${LINE10}${LINE10}${LINE10}${LINE10}${LINE10}${LINE10}WALL_CHAR='|'# --------------------------------------------------------------------------------# global value# --------------------------------------------------------------------------------## err code define#G_ERR_CODE_BASE=0G_ERR_CODE_OK=$(echo "scale=4; $G_ERR_CODE_BASE + 0" | bc)G_ERR_CODE_ERR=$(echo "scale=4; $G_ERR_CODE_BASE + 1" | bc)G_ERR_CODE_USER_NOT_EXIST=$(echo "scale=4; $G_ERR_CODE_BASE + 2" | bc)G_ERR_CODE_USER_NOT_EXIST_BUT_HAVE_HOME_DIR=$(echo "scale=4; $G_ERR_CODE_BASE + 3" | bc)# row info below# games:x:5:60:games:/usr/games:/bin/sh# one row have 7 fields, indicate char is ':'# field 0 is username# field 5 is home dir#g_etc_passwd_row_field_index_user_name=0g_etc_passwd_row_field_index_home_dir=5
# !/bin/bash# @file sh.file_opt_etc_passwd# @brief function operate /etc/passwd# --------------------------------------------------------------------------------# @fn func_get_user_name_and_home_dir_for_one_row_from_etc_passwd# @brief get usrname and homedir from one row from /etc/passwd# @parameter IN, $1, row content# @parameter OUT, array ary_to_return, # ary_to_return[0] = arysize, # ary_to_return[1] is rc, # ary_to_return[2] is username, # ary_to_return[3] = home dir# @return G_ERR_CODE_OK or G_ERR_CODE_ERR# --------------------------------------------------------------------------------function func_get_user_name_and_home_dir_for_one_row_from_etc_passwd() { local ary_to_return local rc=$G_ERR_CODE_ERR local str_user_name="" local str_home_dir="" local str_field="" local IFS_org="" local pos=0 local b_was_get_user_name=false local b_was_get_home_dir=false IFS_org=$IFS IFS=$':' for str_field in $1 do if [ $pos -eq $g_etc_passwd_row_field_index_user_name ] then b_was_get_user_name=true str_user_name=$str_field elif [ $pos -eq $g_etc_passwd_row_field_index_home_dir ] then b_was_get_home_dir=true str_home_dir=$str_field fi pos=$(echo "scale=4; $pos + 1" | bc) # pos++ if [ "$b_was_get_home_dir" = true ] && [ "$b_was_get_home_dir" = true ] then rc=$G_ERR_CODE_OK break fi done IFS=$IFS_org # fill output parameter ary_to_return[0]=3 ary_to_return[1]=$rc ary_to_return[2]=$str_user_name ary_to_return[3]=$str_home_dir echo ${ary_to_return[*]} # this is all array content return $rc}# --------------------------------------------------------------------------------# @fn func_is_user_exist# @brief is user exist# @parameter IN, username# @prarmeter OUT, ary_to_return# ary_to_return[0] = ary size# ary_to_return[1] = return code# ary_to_return[2] = user name# ary_to_return[3] = home dir# @return g_err_code_xx# --------------------------------------------------------------------------------function func_is_user_exist() { # ! because need use echo pass output parameter, so don't echo other messages on function or sub function local ary_to_return local rc=$G_ERR_CODE_ERR local str_user_name="" local str_user_home="" local str_user_name_rv="" local IFS_org="" local str_row_content="" local str_user_home_rv="" local rc_tmp_ary local rc_tmp=0 # user name str_user_name=$1 # user home str_user_home="/home/${str_user_name}" IFS_org=$IFS IFS=$'\n' for str_row_content in $(cat "/etc/passwd") do rc_tmp_ary=$(func_get_user_name_and_home_dir_for_one_row_from_etc_passwd $str_row_content) # rc_tmp_ary = 4 0 speech-dispatcher /var/run/speech-dispatcher rc_tmp=$? str_user_name_rv=$(func_get_ary_by_index 2 $rc_tmp_ary) str_user_home_rv=$(func_get_ary_by_index 3 $rc_tmp_ary) if [ $rc_tmp -eq $G_ERR_CODE_ERR ] then continue elif [ "$str_user_name" = "$str_user_name_rv" ] then # ok : on rc_tmp_ary, can get username and homedir rc=$G_ERR_CODE_OK break; fi done IFS=$IFS_org if [ $rc -eq $G_ERR_CODE_OK ] then # find user in /etc/passwd # set rc, fill ary and echo ary, then to return ary_to_return[0]=3 # parameter counter(3 = $G_ERR_CODE_OK + user_name + user_home_dir) ary_to_return[1]=$rc # reture code ary_to_return[2]=$str_user_name_rv # user name ary_to_return[3]=$str_user_home_rv # user home dir echo ${ary_to_return[*]} # this is all array content return $rc fi # if user name not in /etc/passwd, try to find is the user have home dir ? # before opt a file, please check is file exist. if file is dir, do check also # do check can guard some error message on opt file if ! [ -d $str_user_home ] then rc=$G_ERR_CODE_USER_NOT_EXIST # fill output parameter ary_to_return[0]=3 ary_to_return[1]=$rc ary_to_return[2]=$str_user_name ary_to_return[3]="" echo ${ary_to_return[*]} return $rc fi # ls -d xx # only list dir by give str_user_name_rv=$str_user_name str_user_home_rv=$(ls -d $str_user_home) # e.g. return /home/root rc_tmp=$? #e.g. return 0, 1, or other int value # if dir not exist, rc_tmp = 2 # rc_tmp is number, cmpare use -eq if [ 0 -eq $rc_tmp ] then str_user_home_rv=$str_user_home rc=${G_ERR_CODE_USER_NOT_EXIST_BUT_HAVE_HOME_DIR} else str_user_home_rv="" rc=${G_ERR_CODE_USER_NOT_EXIST} fi # fill ary and echo ary, set rc to return ary_to_return[0]=3 ary_to_return[1]=$rc ary_to_return[2]=$str_user_name_rv ary_to_return[3]=$str_user_home_rv echo ${ary_to_return[*]} # this is all array content return $rc}
# !/bin/bash# @file sh.helper# @brief helper function for other shell script# --------------------------------------------------------------------------------# init# --------------------------------------------------------------------------------function func_init() { local i_index=0 clear # print 25 empty lines for run result for (( i_index=0; i_index < 25; i_index++ )) do echo done}# --------------------------------------------------------------------------------# uinit# --------------------------------------------------------------------------------function func_uinit() { exit 0}# --------------------------------------------------------------------------------# show tail# --------------------------------------------------------------------------------function func_show_tail() { echo -e "${LINE80}" echo -e -n "${WALL_CHAR}" echo -e "\tEND" echo -e "${LINE80}"}# --------------------------------------------------------------------------------# show os info# --------------------------------------------------------------------------------function func_show_os_info() { local str_date=$(date +%Y_%m_%d_%H_%M_%S) # show time echo -e -n "${WALL_CHAR}" echo -e "\t${str_date}" # show shell echo -e -n "${WALL_CHAR}" echo -e "\t${SHELL}" # show language echo -e -n "${WALL_CHAR}" echo -e "\t${LANG}" # show user echo -e -n "${WALL_CHAR}" echo -e "\t${USER}" echo -e "${LINE80}"}# --------------------------------------------------------------------------------# @fn func_show_ary()# @param IN array name# @param IN array self# --------------------------------------------------------------------------------function func_show_ary() { local array_in="" local ary_item="" local i_index=0 local i_index_to_disp=0 array_in=$@ IFS_org=$IFS IFS=$' ' for ary_item in $array_in do # skip $1, this is array name if [ $i_index -ne 0 ] then echo "$1[$i_index_to_disp] = $ary_item" i_index_to_disp=$(echo "scale=4; $i_index_to_disp + 1" | bc) fi i_index=$(echo "scale=4; $i_index + 1" | bc) done IFS=$IFS_org echo}# --------------------------------------------------------------------------------# @fn func_get_ary_by_index()# @brief the all array is {index_obj, ary[0], ary[1], ary[2], ...}# @param IN array index, index base 0, if index is 0, return ary[0], not return index_obj# @param IN array self# @return ary[i]# --------------------------------------------------------------------------------function func_get_ary_by_index() { # ! because need use echo pass output parameter, so don't echo other messages on function or sub function local array_in="" local ary_item="" local i_index=0 local i_index_obj=$1 array_in=$@ i_index_obj=$(echo "scale=4; $i_index_obj + 1" | bc) i_index=0 IFS_org=$IFS IFS=$' ' for ary_item in $array_in do if [ $i_index -eq 0 ] then # $1 is the obj index i_index_obj=$ary_item i_index_obj=$(echo "scale=4; $i_index_obj + 1" | bc) elif [ $i_index -eq $i_index_obj ] then echo "$ary_item" break fi i_index=$(echo "scale=4; $i_index + 1" | bc) done IFS=$IFS_org return 0}
# !/bin/bash# @file sh.prog_version# @brief show this prog version. ./sh.const_define# run time env is debian7.5PROG_NAME="check user exist"PROG_VER="1.0.0.5"PROG_TIME="2018-02-14 10:42"# --------------------------------------------------------------------------------# show title# --------------------------------------------------------------------------------function func_show_title() { echo -e "${LINE80}" echo -e -n "${WALL_CHAR}" echo -e "\t@file\tmain.sh" echo -e -n "${WALL_CHAR}" echo -e "\t@brief\twrap a shell script functin to check user exist" echo -e -n "${WALL_CHAR}" echo -e "\t\tuse array to pass output parameter" echo -e "\t\tnot use any global var" echo -e "\t\tuse my local shell script lib" echo -e "${LINE80}"}# --------------------------------------------------------------------------------# show prog info# --------------------------------------------------------------------------------function func_show_prog_info() { # show prog name echo -e -n "${WALL_CHAR}" echo -e "\t${PROG_NAME}" # show prog version echo -e -n "${WALL_CHAR}" echo -e "\t${PROG_VER}" # show code modify time echo -e -n "${WALL_CHAR}" echo -e "\t${PROG_TIME}" echo -e "${LINE80}"}
# !/bin/bash# @file sh.test_case# @brief test function for other shell script# --------------------------------------------------------------------------------# @fn func_case_gen_ary# @brief gen ary[4] to test# @prarmeter OUT, ary_to_return# ary_to_return[0] = ary size# ary_to_return[1] = return code# ary_to_return[2] = user name# ary_to_return[3] = home dir# @return g_err_code_xx# --------------------------------------------------------------------------------function func_case_gen_ary() { # ! because need use echo pass output parameter, so don't echo other messages on function or sub function local rc=$G_ERR_CODE_USER_NOT_EXIST_BUT_HAVE_HOME_DIR local ary_to_return ary_to_return[0]=3 ary_to_return[1]=$rc ary_to_return[2]="user_name" ary_to_return[3]="user_home_dir" echo ${ary_to_return[*]} # this is all array content return $rc}# --------------------------------------------------------------------------------# save some test case# --------------------------------------------------------------------------------function func_test_case() { # test : gen ary ary_to_return=$(func_case_gen_ary) rc=$? # test : show ary func_show_ary "ary_to_return" $ary_to_return # test : func_get_ary_by_index, index base 0 str_rv=$(func_get_ary_by_index 0 $ary_to_return) echo "str_rv = $str_rv" func_get_ary_by_index 1 $ary_to_return func_get_ary_by_index 2 $ary_to_return ary_element_3=$(func_get_ary_by_index 3 $ary_to_return) echo "ary_to_return[3] = $ary_element_3"}
# !/bin/bash# @file sh.user_info# @brief show user info# --------------------------------------------------------------------------------# fuc_show_user_info# --------------------------------------------------------------------------------function fuc_show_user_info() { local ary_to_return local rc=0 local i_index=0 local ary_val="" local str_user_name="" local str_user_home="" # $1 is user name ary_to_return=$(func_is_user_exist $1) rc=$? # func_show_ary "ary_to_return" $ary_to_return if [ $rc -eq $G_ERR_CODE_OK ] then str_user_name=$(func_get_ary_by_index 2 $ary_to_return) str_user_home=$(func_get_ary_by_index 3 $ary_to_return) echo "user [$str_user_name] exist, user home dir = [$str_user_home])" elif [ $rc -eq $G_ERR_CODE_USER_NOT_EXIST_BUT_HAVE_HOME_DIR ] then str_user_name=$(func_get_ary_by_index 2 $ary_to_return) str_user_home=$(func_get_ary_by_index 3 $ary_to_return) echo "user [$str_user_name] not exist, but have home dir, user home dir = [$str_user_home]" elif [ $rc -eq $G_ERR_CODE_USER_NOT_EXIST ] then str_user_name=$(func_get_ary_by_index 2 $ary_to_return) echo "user [$str_user_name] not exist" else echo "unknow return code, please contact admin" fi echo}
2018_02_16
工程大了之后,库最好放在其他目录中,主工程和库目录分开。
试了一下,果真可以。代码是一样的,包含库时指定其他库的路径名称,用相对路径试了一下,是可以的。如果库分的合理,需要改变库包含路径的就是主工程(如果工程不复杂的话).
如果包含同目录下的库,也可以写成 . ./sh.my_lib的形式整理后的工程目录结构
root@debian750devmin:/home/dev# find .../.bash_history./test_case./test_case/sh.test_case./readme.txt./helper./helper/sh.helper./helper/sh.file_opt_etc_passwd./helper/sh.user_info./main.sh./common./common/sh.os_info./common/sh.const_define./common/sh.prog_version
包含库路径变化了的sh
# !/bin/bash# @file main.sh# @brief wrap a shell script functin to check user exist, # use array to pass output parameter, not use any global var# include other shell script. ./common/sh.const_define. ./common/sh.prog_version. ./common/sh.os_info. ./helper/sh.helper. ./helper/sh.file_opt_etc_passwd. ./helper/sh.user_info. ./test_case/sh.test_case# --------------------------------------------------------------------------------# do task# --------------------------------------------------------------------------------function func_do_task() { # test user exist and have home dir fuc_show_user_info "root" # user not exist, but have home dir fuc_show_user_info "dev" # user not exist and have not home dir fuc_show_user_info "user_not_exist"}# --------------------------------------------------------------------------------# main shell script# --------------------------------------------------------------------------------func_initfunc_show_titlefunc_show_prog_infofunc_show_os_info# func_test_casefunc_do_taskfunc_show_tailfunc_uinit
转载地址:https://lostspeed.blog.csdn.net/article/details/79324753 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
表示我来过!
[***.240.166.169]2024年04月13日 01时04分43秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
pip无法安装:换成国内镜像
2019-05-01
python安装mysqlclient[MySQLdb]
2019-05-01
性能测试的必要性评估以及评估方法
2019-05-01
性能测试需求分析
2019-05-01
性能测试需求评审
2019-05-01
性能测试实施流程
2019-05-01
Jmeter在多线程当中对某个http请求进行循环读取配置文件
2019-05-01
Python读取配置文件中文乱码问题
2019-05-01
使用Spark读写外部存储介质(Mysql、Hbase、Redis)
2019-05-01
Spark学习——利用Mleap部署spark pipeline模型
2019-05-01
手写LogisticRegression
2019-05-01
SQL经典题目总结
2019-05-01
剑指offer编程题,一周刷完
2019-05-01
推荐系统初学
2019-05-01
Map的遍历和排序
2019-05-01
约瑟夫环问题
2019-05-01
springboot+log4j2体验
2019-05-01
redis集群启动方式
2019-05-01
ubuntu系统开机自启动方式
2019-05-01